参数化类型的数组

Teg*_*shi 2 java generics

我无法确定以下RHS预期的类型参数

ArrayList<Pair<ParseNode,ParseNode>>[] nodes = new ArrayList[indexes.length];
Run Code Online (Sandbox Code Playgroud)

为什么副本<Pair<ParseNode,ParseNode>>不合法?

Aff*_*ffe 9

具体的参数化类型的阵列固有地被破坏.记住数组是协变的,数组类型检查是运行时操作.在运行时,所有的仿制药已经被删除类型,所以数组存储校验不能告诉<Pair<ParseNode, ParseNode>><Pair<BigInteger,IOException>>.

泛型的基本契约是"我,编译器,承诺如果你编写不产生警告的代码,你将永远不会在运行时获得类转换异常."

编译器也不能向你保证,如果某个不是a的东西ArrayList<Pair<ParseNode,ParseNode>>被放入该数组,它将能够给你一个编译时错误.如果添加错误的类型,运行时系统也不能保证你会得到一个ArrayStoreException(就像语言规范所说的那样),而不是稍后当你把它取出时的ClassCastException.(第二部分实际上是为什么它实际上是非法的而不仅仅是一个警告,它会导致一个不符合语言规范的数组.)

因此,它不允许您以这种方式声明它们并迫使您承认"不安全"警告.这样它就说"我告诉过你我不能保证不会因使用这个数组而导致任何类别转换异常,而是确保你只把正确的东西放在这里."


Mer*_*nne 5

Java不支持通用数组.数组是协变的,泛型不是.这意味着如果A类扩展了B类,那么A []也是B [].和代码

A[] a = new A[10];
B[] b = a;
Run Code Online (Sandbox Code Playgroud)

是合法的.

但是对于泛型来说并不相同.你不能分配Foo<T>Foo<X>甚至如果T X.延伸和所谓元素Foo<T>[]无法被保证类型安全.

编辑 请原谅我只是链接,但我找到了Java理论和实践:泛型得到的文章,这解释了关于数组协方差的一切比我甚至梦想的更好.