参数化类型的java数组
我很难弄清楚在下面的RHS中需要什么类型参数
ArrayList<Pair<ParseNode,ParseNode>>[] nodes = new ArrayList[indexes.length];
为什么<Pair<ParseNode,ParseNode>>
的副本不合法
你可以在下面搜索框中键入要查询的问题!
我很难弄清楚在下面的RHS中需要什么类型参数
ArrayList<Pair<ParseNode,ParseNode>>[] nodes = new ArrayList[indexes.length];
为什么<Pair<ParseNode,ParseNode>>
的副本不合法
# 1 楼答案
混凝土参数化类型的数组本质上是破碎的。请记住,数组是协变的,数组类型检查是一个运行时操作。在运行时,所有泛型都已被类型擦除,因此数组存储检查无法区分
<Pair<ParseNode, ParseNode>>
和<Pair<BigInteger,IOException>>
泛型的基本约定是“我,编译器,承诺如果您编写的代码不生成警告,您将永远不会在运行时得到类强制转换异常。”
编译器也不能向您保证,如果将非
ArrayList<Pair<ParseNode,ParseNode>>
的内容放入该数组中,它将能够给您一个编译时错误。如果您添加了错误的类型,运行时系统也不能保证您将获得ArrayStoreException(就像语言规范所说的那样),而不是在稍后将其取出时获得ClassCastException。(第二部分是为什么它实际上是非法的,而不仅仅是一个警告,它将导致一个不符合语言规范的数组。)因此,它不允许您以这种方式声明它们,并强制您承认“不安全”警告。这样,它就说:“我告诉过你,我不能保证使用这个数组不会导致任何类强制转换异常,你必须确保你只在这里放正确的东西。”
# 2 楼答案
不要使用数组。使用另一个ArrayList
# 3 楼答案
Java不支持泛型数组。数组是协变的,泛型不是。这意味着如果类A扩展了类B,那么A[]也是B[]。和代码
这是合法的
但泛型的情况不同。即使T扩展了X,也不能将
Foo<T>
分配给Foo<X>
,因此Foo<T>[]
的元素不能保证类型安全编辑 请原谅我只是链接一下,但我发现了Java theory and practice: Generics gotchas篇文章,它比我想象的更好地解释了关于数组协方差的一切