为什么这段代码有效
ArrayList<?>[] arr = new ArrayList<?>[2];
但是下面两个不是?
ArrayList<? extends Object>[] arr = new ArrayList<? extends Object>[2];
ArrayList<? super Object>[] arr = new ArrayList<? super Object>[2];
最后两行产生编译错误;
error: generic array creation.
请说明区别。
更新
另一方面ArrayList<?>[] arr = new ArrayList<?>[2];
编译不错但是
ArrayList<?> arr = new ArrayList<?>();
不是。
最佳答案
这里有几个问题,让我们依次看一下:
类型绑定(bind)(即
extends Object
)只能在声明类型时声明,不能在实例化对象时使用。例如
ArrayList<? extends Object> ab = new ArrayList<? extends Object>(); // error
ArrayList<? extends Object> ac = new ArrayList<String>(); // okay
数组不支持类型参数,例如:
List<Integer>[] arrayOfLists = new List<Integer>[2]; // compile time error
List<Integer> list = new List<Integer>(); // okay
Oracle 记录了此限制的原因 here .
<?>
可以在声明类型参数和数组时使用。添加它是为了在混合使用和不使用泛型的 Java 代码时帮助避免“未经检查的异常”错误。它的意思是“未知的通用类型”。关于无限通配符的更多详细信息 here .ArrayList<?>[] arr = new ArrayList<?>[2];
出于上述原因有效。但是它的用途非常有限,因为只能将 null 分配给声明为
<?>
的类型。 .arr[0] = null; // compiles
arr[1] = new Object(); // compile time error
Oracle 提供以下 Guide on using wildcards这将有助于了解何时使用此通配符。
<?>
不能用于实例化对象。例如ArrayList<?> arr = new ArrayList<?>(); // does not compile
ArrayList<?> arr2 = new ArrayList<>(); // but this does
ArrayList<?> arr3 = new ArrayList<String>(); // and so does this
但是仍然存在使用
<?>
的问题只接受 null。arr3.add( " " ); // does not compile even though it was instantiated with String
arr3.add( null ); // compiles just fine
关于java - 创建无界和有界通配符类型数组之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26139725/