[英]Fully qualified generics type casting error overlooked by Java compiler?
Generics are knowingly meant for stronger type checking at compile time. 众所周知,泛型意味着在编译时进行更强大的类型检查。 However, while studying the official Java tutorial, I ran into this: 但是,在研究官方Java教程时,我遇到了这个问题:
However, in some cases the compiler knows that a type parameter is always valid and allows the cast. For example:
List<String> l1 = ...;
ArrayList<String> l2 = (ArrayList<String>)l1; // OK
from http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast . 来自http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast 。
I've tried and tested this (which fully reflects the documentation): 我已经尝试并测试了这一点(它完全反映了文档):
List<String> l1 = new LinkedList<String>();
ArrayList<String> l2 = (ArrayList<String>)l1; // OK
Although everything is pretty explicit (no assignment to an Object
variable, no wilcarding, etc), the compiler fails to predict the runtime error that shows up afterwards: 尽管一切都非常明确(没有分配给Object
变量,没有使用通配符等),但是编译器无法预测随后出现的运行时错误:
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedList cannot be cast to java.util.ArrayList
100% puzzled. 100%不解。
Reread the link -- it's not stating you can cast a LinkedList
to an ArrayList
. 重新读取链接-并不是说您可以将LinkedList
转换为ArrayList
。 It's stating that you can downcast a List
of String
to the (presumably programmer-known) type of ArrayList
of String
. 它说明您可以向下转换一个List
的String
到(大概是程序员知道)类型的ArrayList
的String
。 What they're attempting to illustrate is the difference between the generic type parameters. 他们试图说明的是通用类型参数之间的差异。 Their first example shows casting from a collection of Integer
to a collection of Number
, which is not allowed. 他们的第一个示例显示了从Integer
集合到Number
集合的强制转换。
Typically, you cannot cast to a parameterized type unless it is parameterized by unbounded wildcards. 通常,除非使用不受限制的通配符对其进行参数化,否则无法将其转换为参数化类型。 For example: 例如:
List li = new ArrayList<>(); 列表li = new ArrayList <>(); List ln = (List) li; 列表ln =(列表)li; // compile-time error //编译时错误
However, in some cases the compiler knows that a type parameter is always valid and allows the cast. 但是,在某些情况下,编译器知道类型参数始终有效并允许强制转换。 For example: 例如:
List l1 = ...; 列表l1 = ...; ArrayList l2 = (ArrayList)l1; ArrayList l2 =(ArrayList)l1; // OK // 好
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.