未选中通配符泛型类型和泛型类型之间的强制转换



请帮助我理解为什么取消选中此强制转换:

 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,让它接受任何类型的数字,在本例中是一个双。当然,当您迭代原始集合时,期望整数,当您找到一个实际上不是整数的集合时,您的代码将失败。

这就是为什么编译器发出警告是合乎逻辑的,这就是为什么不听它是危险的。字符串是Java中的最后一个类这一事实就是为什么在您的特定情况下,您可能找不到任何解决我刚才描述的这个问题的方案的原因。但在其他情况下,这是可能的。

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

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

更多阅读:

  • 是列表<狗>List<动物>?为什么';t Java';s泛型隐含多态性

最新更新