当前位置:  开发笔记 > 编程语言 > 正文

Java 9或更高版本中的预计泛型专业化,与List <int>:.remove()将如何工作?

如何解决《Java9或更高版本中的预计泛型专业化,与List<int>:.remove()将如何工作?》经验,为你挑选了1个好方法。

通用专业化和值类型是未来JVM的预计特征; 链接到瓦尔哈拉项目页面在这里.

现在,根据我的理解,可以宣布:

final List myList = new ArrayList<>(); // for instance

但是接着List定义了另一个.remove()方法,除了在Collection接口中定义的方法之外,它接受int一个参数,它是要删除的列表中的索引; 这就是为什么,目前,list以下示例中的内容:

final List list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.remove(2);

将是[1, 2]和不[1, 3](选择最具体的过载).

但是,如果将来我们能够声明一个List,我们就会遇到一个问题:该remove方法会选择多少重载?



1> Tunaki..:

这个答案是基于Brian Goetz于2014年12月发表的这篇论文.这是我在这个问题上能找到的最新内容.但请注意,该论文是一个"非正式草图",因此对于您的问题尚无定论.

首先,a List不会是List(Subtyping)的子类型:

最初,它似乎也Box可能是原始的子类型Box.但是,根据我们的翻译策略,Box类不能是任何类所代表的超类Box,因为Box那样会有一个t类型的字段Object,而t应该是类型int.所以Box不能成为原始的子类型Box.(并且出于同样的原因,Box不能成为子类型Box.)

...

由于泛型是不变的,因此List不是一个子类型就不足为奇了List.这里有点令人惊讶的是,专用类型无法与其原始对应物进行互操作.但是,这不是一个不合理的限制; 不仅不鼓励原始类型(仅为了支持从非通用代码逐渐迁移到通用代码而引入),但仍然可以使用通用方法编写完全通用的代码 - 请参阅"通用方法".

本文还列出了"迁移挑战",而引用原语重载(问题是你的问题)就是其中之一:

今天有效的一些过载在专业化下会成为问题.例如,如果专门用于以下方法,这些方法就会出现问题T=int:

public void remove(int position);
public void remove(T element);

这种重载在专业化方面(生成什么方法)和重载选择方(调用哪个方法)都会有问题.

建议的解决方案被称为"剥离"技术:

考虑类似List的类中的重载对:

interface ListLike {
    public void remove(int position);
    public void remove(T element);
}

ListLikewill的现有用途都涉及参考实例化,因为这些是预专业化世界中当前允许的唯一实例.请注意,虽然兼容性要求引用实例化具有这两种方法,但它不需要任何非引用实例化(因为当前都不存在).

剥离背后的直觉是观察到,虽然我们习惯于将现有的思想ListLike视为泛型类型,但它实际上可能是所有实例化中通用的类型的并集,以及仅在引用中是通用的类型instantations.

如果我们在后专业化世界中从头开始编写这个类,我们可能会把它写成:

interface ListLike {
    void removeByIndex(int position);
    void removeByValue(T element);
}

但是,现在这样的改变既不是源兼容的,也不是二进制兼容的.但是,剥离允许我们将这些方法添加到通用层,并在特定于引用的层中实现它们,而不需要它们在特化中,恢复兼容性:

interface ListLike {
    // New methods added to the generic layer
    void removeByValue(T element);
    void removeByIndex(int pos);

    layer {
        // Abstract methods that exist only in the ref layer
        void remove(int pos);
        void remove(T element);

        // Default implementations of the new generic methods
        default void removeByIndex(int pos) { remove(pos); }
        default void removeByValue(T t) { remove(t); }
    }
}

现在,参考实例有remove(T),和remove(int)(以及新的方法removeByIndexremoveByValue),以确保兼容性,并具有专业化的nonproblematic重载removeByValue(T)removeByIndex(int).现有的实现ListLike将继续编译,因为新方法具有参考特化的默认实现(它简单地桥接到现有的移除方法).对于值实例化,removeByIndex并且removeByValue被视为抽象且必须提供,但删除根本不存在.

该技术还实现了"按部件实现"技术; 可以在通用层中声明方法抽象,并在值层和参考层中提供具体实现.如果我们允许图层T=int,它也将启用"专业化专业化"技术.

使用这种技术,将保持向后兼容性removeByValue并且removeByIndex将使用新方法.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有