繁体   English   中英

为什么在使用“扩展”时需要泛型泛型?

[英]Why need cast generics when use 'extends'?

为什么在使用T extends A时需要强制转换为List<T>

class A{}
public <T extends A> List<T> someMethod() {
    List<A> list = new ArrayList<>();
    List<T> result1 = list; // !! Does not compile, why?
    List<T> result2 = (List<T>) list; // ok, but why need cast?

    return  result2;
}

阅读有关“通配符和子类型”的文档 :在您的示例中, List<T>List<A>的子类型。 您不能将实例分配给其子类型的变量。

想象一个更简单的情况: NumberInteger

Number n = ...;
Integer i;
i = n;  // error
i = (Integer) n;

您可以抛弃编译错误,并且只要知道变量发生了什么就可以正常工作。 如果nDouble ,则将得到ClassCastException


使用示例中的集合,强制转换将始终有效,因为在运行时不检查泛型类型信息,即,它只是从List强制转换为List

但是,当您拥有List类的通用类型时,还有另一种复杂度:使用通用类型,您可以保证该列表所包含的内容(将其视为对自己,使用代码的开发人员和编译器的承诺)。 通过分配“更广泛”的列表,以后使用时可能会遇到麻烦。

class Apple extends Fruit
class Orange extends Fruit

List<Fruit> fruitBasket = Arrays.asList(new Orange(), new Apple());
List<Apple> applesOnly;
applesOnly = (List<Apple>) fruitBasket;

for (Apple apple : applesOnly) // ClassCastException because of the Orange in fruitBasket

在此示例中,您通过分配fruitBasket违反了applesOnly仅包含苹果的承诺。 这就是为什么大多数IDE在投射泛型时都会给您至少一个警告的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM