Java 创建无界和有界通配符类型数组之间的区别?
为什么这个代码是有效的Java 创建无界和有界通配符类型数组之间的区别?,java,arrays,generics,wildcard,bounded-wildcard,Java,Arrays,Generics,Wildcard,Bounded Wildcard,为什么这个代码是有效的 ArrayList<?>[] arr = new ArrayList<?>[2]; ArrayList[]arr=新的ArrayList[2]; 但以下两个不是 ArrayList<? extends Object>[] arr = new ArrayList<? extends Object>[2]; ArrayList<? super Object>[] arr = new ArrayList<?
ArrayList<?>[] arr = new ArrayList<?>[2];
ArrayList[]arr=新的ArrayList[2];
但以下两个不是
ArrayList<? extends Object>[] arr = new ArrayList<? extends Object>[2];
ArrayList<? super Object>[] arr = new ArrayList<? super Object>[2];
ArrayList[]arr=新的ArrayList[2]代码>编译良好,但是
ArrayList<?> arr = new ArrayList<?>();
ArrayList arr=new ArrayList();
不是。这里有几个问题,让我们依次看看:
类型绑定(即扩展对象
)只能在声明类型时声明,不能在实例化对象时使用
比如说
ArrayList
可以在声明类型参数时使用,也可以与数组一起使用。添加它是为了在混合使用泛型和不使用泛型的Java代码时避免“未检查的异常”错误。它的意思是“未知的泛型类型”。更多关于无界通配符的详细信息
ArrayList[]arr=新的ArrayList[2]代码>
基于上述原因,本协议有效。但是,它的用途非常有限,因为只有null可以分配给声明为
的类型
arr[0]=null;//编译
arr[1]=新对象();//编译时错误
Oracle提供了以下内容,有助于了解何时使用此通配符
不能用于实例化对象。比如说
ArrayList arr=new ArrayList();//不编译
ArrayList arr2=new ArrayList();//但这确实是
ArrayList arr3=new ArrayList();//这也是如此
但是仍然存在一个问题,即使用
只接受null
arr3.添加(“”;//即使它是用字符串实例化的,也不会编译
arr3.add(null);//编译得很好
您必须首先理解为什么不允许创建参数化类型的数组。这是因为数组在运行时检查插入的元素是否为组件类型的实例(lainstanceof
)。无法检查参数化类型的instanceof
,因为对象对创建它时使用的类型参数没有感觉instanceof ArrayList
在Java中是非法的,就像Java中允许的instanceof ArrayList
一样,因为它不需要关于对象类型参数的信息。(顺便说一句,instanceof ArrayList+1-我没有考虑与数组的交互。只有类型声明本身。也许第一个问题应该是,为什么下面的内容不编译:-不,我知道it@gstackoverflow对不起,我没听懂你的话。你什么意思?@gstacking当你有机会吸收时,我可以进行任何澄清。但关键点是,“Java不支持泛型数组”。Period.HavingArrayList[]
的工作在某种程度上是一种转移注意力的工作,将使用泛型的代码与不支持泛型的代码集成在一起是一种特殊情况。以下是一个优秀的教程: