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);//编译得很好


  • 您必须首先理解为什么不允许创建参数化类型的数组。这是因为数组在运行时检查插入的元素是否为组件类型的实例(la
    instanceof
    )。无法检查参数化类型的
    instanceof
    ,因为对象对创建它时使用的类型参数没有感觉
    instanceof ArrayList
    在Java中是非法的,就像Java中允许的
    instanceof ArrayList
    一样,因为它不需要关于对象类型参数的信息。(顺便说一句,
    instanceof ArrayList+1-我没有考虑与数组的交互。只有类型声明本身。也许第一个问题应该是,为什么下面的内容不编译:-不,我知道it@gstackoverflow对不起,我没听懂你的话。你什么意思?@gstacking当你有机会吸收时,我可以进行任何澄清。但关键点是,“Java不支持泛型数组”。Period.Having
    ArrayList[]
    的工作在某种程度上是一种转移注意力的工作,将使用泛型的代码与不支持泛型的代码集成在一起是一种特殊情况。以下是一个优秀的教程: