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

使用addAll()编译器的ArrayList显示泛型的不同行为

如何解决《使用addAll()编译器的ArrayList显示泛型的不同行为》经验,为你挑选了2个好方法。

有人可以向我解释以下行为吗?

我有一个列表X并使用该addAll()方法添加元素.这些元素由使用泛型类型的方法返回.方法getA()返回< T extends A >A作为一类.方法getI()返回< T extends I >I作为一个接口(见下面的代码).

差异:listX.addAll(getA())我得到编译错误(如预期的那样),但是listX.addAll(getI())编译(当元素被强制转换时抛出运行时错误X).

简化代码:

interface I {}
class A implements I {}

class X {}

public void test() {   
    List listX = new ArrayList<>();
    listX.addAll(getA());

    listX.addAll(getI());
    for (X x : listX) {}
}
public  List getA() {
    return new ArrayList<>();
}
public  List getI() {
    return new ArrayList<>();
}

我错过了什么吗?我不应该两次都得到编译错误吗?

对于Java 8来说,这种行为似乎是新的,下面的版本我在这两种情况下都遇到了编译器错误.



1> Gonen I..:

我想简化问题,Shmosel的答案如下:

interface I {}
class A implements I {}

class X {}

public void test() {   
    X temp = getI();  // compiles
    X temp2 = getA();  // does not compile
}

public  T getI() {  
    return null;
}
public  T getA() {  
    return null;
}

getI()可以返回扩展X并实现I的东西,这就是它编译的原因.通常,它实际返回的类型取决于某些东西,例如传递给函数的参数.

getA()不能返回一个X的东西,因为它返回一个扩展A的东西,它不会扩展X.



2> shmosel..:

listX.addAll(getA());不编译,因为没有可能的子类也是X它的子类A.

listX.addAll(getI());编译,因为可能有一个子类X也实现I.


同时实现`I`的`X`的子类应声明为``而不仅仅是``.
@NicolasFilotto这里的onus是在`getI()`方法,以确保它可以安全地返回`List `,无论什么`T`可能.更合理的情况是使用类型"T"的输入参数可以用来产生返回值.OP的情况很不寻常,因为在没有编译错误或警告的情况下,无法返回包含除空项之外的任何内容的列表.由于他正在返回一个空列表,因此非常安全.
@NicolasFilotto`getI()`并没有声明`T`扩展了`X`.它只是承诺返回一个`T`列表,并让调用者确定它是什么类型.调用者有责任确保其类型参数与"I"兼容,在"X"的情况下,它是.
@SrikanthA我希望它在JLS中,如果有的话.但[正如我所提到的](http://stackoverflow.com/questions/41673016/arraylist-using-addall-compiler-shows-different-behavior-with-generics/41673357#comment70544429_41673016),我无法重现之间的差异Java 7和Java 8.
@Nicolas Filotto:这里没有错误,因为代码是正确的.只要列表在问题代码中保持为空,它就不会在运行时抛出.很快,当您尝试使用它做一些有意义的事情时,会出现警告甚至错误.
@Srikanth答:规则没有改变.更改的内容是[改进的类型推断](https://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html#javase8),它使编译器能够推断出类型嵌套调用用例.
推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有