创建数组以在 Java 中存储泛型类型

2022-09-01 03:19:37

假设我必须创建一个数组来存储 ArrayList 的整数,数组大小为 10。

下面的代码将做到这一点:

ArrayList<Integer>[] pl2 = new ArrayList[10]; 

问题 1:

在我看来,更合适的代码将是

ArrayList<Integer>[] pl2 = new ArrayList<Integer>[10];    

为什么这不起作用?

问题 2:

以下两种编译

  1. ArrayList<Integer>[] pl2 = new ArrayList[10];
  2. ArrayList[] pl3 = new ArrayList[10];

就 和 的参考声明而言,有什么区别?pl2pl3


答案 1

泛型信息仅在编译时重要,它告诉编译器哪种类型可以放入数组中,在运行时,所有泛型信息都将被删除,因此重要的是如何声明泛型类型。

引自 Think in Java:

说您无法创建泛型类型的数组并不完全正确。没错,编译器不允许您实例化泛型类型的数组。但是,它将允许您创建对此类数组的引用。例如:

List<String>[] ls; 

这通过编译器而没有投诉。虽然您无法创建包含泛型的实际数组对象,但可以创建非生成类型的数组并对其进行强制转换:

//: arrays/ArrayOfGenerics.java 
// It is possible to create arrays of generics. 
import java.util.*; 

public class ArrayOfGenerics { 
    @SuppressWarnings("unchecked") 
    public static void main(String[] args) { 
        List<String>[] ls; 
        List[] la = new List[10]; 
        ls = (List<String>[])la; // "Unchecked" warning 
        ls[0] = new ArrayList<String>(); 
        // Compile-time checking produces an error: 
        //! ls[1] = new ArrayList<Integer>(); 

        // The problem: List<String> is a subtype of Object 
        Object[] objects = ls; // So assignment is OK 
        // Compiles and runs without complaint: 
        objects[1] = new ArrayList<Integer>(); 

        // However, if your needs are straightforward it is 
        // possible to create an array of generics, albeit 
        // with an "unchecked" warning: 
        List<BerylliumSphere>[] spheres = 
           (List<BerylliumSphere>[])new List[10]; 
        for(int i = 0; i < spheres.length; i++) 
           spheres[i] = new ArrayList<BerylliumSphere>(); 
    } 
}

一旦你有了对List[]的引用,你可以看到你得到了一些编译时检查。问题是数组是协变的,所以 List[] 也是一个 Object[],你可以用它来将 ArrayList 分配到数组中,在编译时或运行时都没有错误。

但是,如果您知道您不会进行upcast并且您的需求相对简单,则可以创建一个泛型数组,这将提供基本的编译时类型检查。但是,泛型容器实际上总是比泛型数组更好的选择。


答案 2

问题 1:

基本上,这是Java语言禁止的。这在泛型的 Java 语言规范中有所介绍

当您使用时

ArrayList<Integer>[] pl2 = new ArrayList[10];    // warning

您会收到编译器警告,因为下面的示例将编译(为每行代码生成警告):

ArrayList wrongRawArrayList = new ArrayList();      // warning
wrongRawArrayList.add("string1");                   // warning 
wrongRawArrayList.add("string2");                   // warning  

pl2[0] = wrongRawArrayList;                         // warning 

但是现在你的数组,应该包含 ,包含完全错误的对象。ArrayListIntegerArrayListString

问题 2:

正如已经回答的那样,声明 of 为您提供了编译时检查,并使您在从 中获取项目时免于使用强制转换。p12ArrayList

稍作修改的上一个示例:

ArrayList<Integer>[] pl2 = new ArrayList[10];                // warning 

ArrayList<String> wrongArrayList = new ArrayList<String>();  // OK!
wrongArrayList.add("string1");                               // OK! 
wrongArrayList.add("string2");                               // OK!

pl2[0] = wrongArrayList;                                     // ERROR

现在,由于您使用的是泛型,因此无法编译。但是,如果您使用

ArrayList[] pl2 = new ArrayList[10]; 

您将获得与第一个示例中相同的结果。


推荐