繁体   English   中英

通配符泛型和泛型之间未经检查的强制转换

[英]Unchecked cast between wildcard generic type and generic type

请帮助我了解为什么未选中此演员表:

 List<? extends String> t= ...;
 List<String> t2=(List<String>)t;

应该是完全安全的……我想可能已经有人问过了,但是我找不到它……关于泛型的太多问题! 我经常使用泛型,但是这个疑问一直存在……谢谢。

编辑:如前所述,我应该使用非最终课程。 所以:

List<? extends ConfigurationAdapter> t= new ArrayList<DATASOURCE_ConfigurationAdapter>();
List<ConfigurationAdapter> t2=(List<ConfigurationAdapter>)t;

这可行。 我不明白为什么它没有被选中。

我想一个例子可以解释警告的原因。

但是,让我们使用其他类型,因为在Java中字符串实际上不能具有子类型。

List<Integer> integers = new ArrayList<>(asList(1,2,3,4,5));
List<? extends Number> anyNumbers = integers;

现在,假设我们强制执行您正在执行的演员表,想象您甚至可以在没有警告的情况下进行

List<Number> numbers = (List<Number>) anyNumbers;

现在,您可以执行以下操作:

numbers.add(3.5);

后来,在代码的其他位置,有人试图使用原始集合,如下所示:

for(Integer myInt: integers) { //ClassCastException

}

之所以收到ClassCastException,是因为您现在违反了类型系统的期望。 原始集合只应接受Integers,但是您设法使Java欺骗以使其接受任何类型的数字,在这种情况下为双精度。 当然,当您遍历原始集合并期望使用整数时,如果发现实际上不是整数的代码,则代码将失败。

因此,编译器发出警告是合乎逻辑的,这就是为什么不听警告很危险。 而且String是Java中的最终类这一事实是为什么在您的特殊情况下您可能找不到我刚刚描述的解决此问题的任何方案的原因。 但是对于其他情况,这是可能的。

对于String来说,它是完全安全的,您可以忽略警告。 对于类型为final class类型的任何类型绑定,也是如此。

对于任何其他类型,分配给t的值的类型可能是List<SubtypeOfTheBound> 在这种情况下,无法将其分配给List<Bound>

更多阅读:

暂无
暂无

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

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