创建无界和有界外卡类型数组之间的区别?
为什么这段代码有效
ArrayList[] arr = new ArrayList[2];
但以下两个不是?
ArrayList[] arr = new ArrayList[2]; ArrayList[] arr = new ArrayList[2];
最后两行生成编译错误;
错误:通用数组创建。
请澄清差异。
更新
另一方面, ArrayList[] arr = new ArrayList[2];
编译好但是
ArrayList arr = new ArrayList();
不。
这里有一些问题,让我们依次看一下:
-
类型绑定(即
extends Object
)只能在声明类型时声明,在实例化对象时不能使用它。例如
ArrayList extends Object> ab = new ArrayList extends Object>(); // error
ArrayList extends Object> ab = new ArrayList extends Object>(); // error
ArrayList extends Object> ac = new ArrayList
(); // okay ArrayList extends Object> ac = new ArrayList
(); // okay -
数组不支持类型参数,例如:
List
[] arrayOfLists = new List [2]; // compile time error List
[] arrayOfLists = new List [2]; // compile time error List
list = new List (); // okay List
list = new List (); // okay Oracle在此处记录了此限制的原因。
-
声明类型参数和数组时可以使用
>
。 添加它是为了在混合使用和不使用generics的Java代码时帮助避免“未经检查的exception”错误。 它意味着’未知的通用类型’。 这里有关于无界外卡的更多细节。ArrayList>[] arr = new ArrayList>[2];
由于上述原因有效。 但是它的使用非常有限,因为只能将null赋给声明为
>
类型。arr[0] = null; // compiles
arr[1] = new Object(); // compile time error
Oracle提供了以下有关使用通配符的指南,这将有助于了解何时使用此通配符。
-
>
不能用于实例化对象。 例如ArrayList> arr = new ArrayList>(); // does not compile
ArrayList> arr2 = new ArrayList<>(); // but this does
ArrayList> arr3 = new ArrayList
(); // and so does this 但是仍有一个问题,即使用
>
只接受null。arr3.add( " " ); // does not compile even though it was instantiated with String
arr3.add( null ); // compiles just fine
您必须首先了解为什么不允许创建参数化类型的数组。 这是因为数组在运行时检查插入的元素是组件类型的instanceof
(la instanceof
)。 无法检查参数化类型的instanceof
,因为对象不具有与其创建的类型参数的含义。 instanceof ArrayList
在Java中是非法的,就像instanceof ArrayList extends Number>
instanceof ArrayList extends Number>
,但Java中允许使用instanceof ArrayList>
,因为它不需要有关对象的类型参数的信息。 (顺便说一下, instanceof ArrayList extends Object>
和instanceof ArrayList super Object>
也是非法的。)
从概念上讲, ArrayList extends Object>
ArrayList extends Object>
与ArrayList>
几乎完全相同(虽然存在细微差别但不相关),但为了语法的一致性, new ArrayList extends X>[...]
new ArrayList extends X>[...]
不允许任何X.