在下面,我在第5行得到一个运行时异常,而不是第4行。这个演员实际上在做什么? 任何有关阅读的见解或链接都会很棒。
List list = new LinkedList();
list.add(new Date());
list.add("Hello");
List<String> list2 = (List<String>)list;
String value = list2.get(1);
答案 0 :(得分:3)
演员实际上在做什么?
执行时没什么。这就是为什么你会收到警告说它是未经检查的演员 - 它没有真正检查任何东西,因为对象本身(在执行时) )没有成为List<String>
的概念 - 它只是一个列表。如果你有:
Object x = ...;
List<String> list = (List<String>) x;
然后检查x
是否指向某些种类的列表......但它不会检查&#34;字符串&#34;列表。
遗憾的是,这是Java泛型的工作方式:(
答案 1 :(得分:2)
编译器在擦除之前检查泛型。如下所示:
final List<String> strings = ...
strings.add(new Date());
将在编译时获取。
检查泛型后,编译器会删除它们,这称为type erasure。因此,在执行时,泛型不存在。
所以,演员:
final List list = new LinkedList();
final List<String> list2 = (List<String>)list;
实际上 nothing ,因为编译器只能检查list
是List
,它是什么。它不会检查内容。
但是,编译器会在此警告您缺少类型检查:
unchecked call to add(E) as a member of the raw type java.util.List
unchecked call to add(E) as a member of the raw type java.util.List
unchecked cast
required: java.util.List<java.lang.String>
found: java.util.List
前两个警告与添加未知类型List
的项目有关 - 这是因为您可以执行相反操作,这会在运行时导致问题:
List<String> strings = new ArrayList<>();
List raw = strings;
第三个警告是关于从List
到List<String>
的不安全转换。
事实上你甚至可以这样做(虽然我不建议你这样做):
List<String> strings = new ArrayList<>();
List<Date> dates = (List<Date>) (List) strings;