简体   繁体   English

Java编译器忽略了完全合格的泛型类型转换错误?

[英]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 . 它说明您可以向下转换一个ListString到(大概是程序员知道)类型的ArrayListString 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.

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