Java 创建泛型数组

原文:https://www.studytonight.com/java-examples/creating-generic-array-in-java

数组用于存储相似类型数据的集合。用 Java 创建一个通用数组可能有点复杂。数组在运行时使用其元素的类型信息来分配内存。但是在泛型的情况下,由于类型擦除,该信息不可用。

泛型在编译时检查类型信息,在运行时没有信息可用。

对于数组,类型信息在运行时被检查,因为它们是协变的。这意味着我们可以将子类型数组赋给父类型(就像字符串[]赋给对象[])。

String[] strArr = new String[5];
Object[] objArr = strArr; //No Error

上述代码不会返回任何编译时错误。我们还可以向上面的数组添加不同的对象,而不用担心任何编译错误。但是对所有元素的类型检查是在运行时对数组进行的。如果在运行时发现任何差异,那么我们将得到ArrayStoreException

public class Demo
{
    public static void main(String[] args)
    {
        String[] strArr = new String[5];
        Object[] objArr = strArr; //No Error
        objArr[0] = new Object();
        objArr[1] = new Exception();
    }
}

线程“main”Java . lang . arraystorexception:Java . lang . object 在 Demo.main(Demo.java:7)出现异常

建议使用像列表这样的集合框架,而不是通用数组。但是,如果我们在编译时有关于类型的一些信息,我们可以创建一个泛型数组。让我们学习如何在 Java 中创建一个泛型数组。

使用对象数组创建通用数组

我们可以创建一个带有对象数组的泛型类来模仿泛型数组。我们将在本课中使用一个get()方法和一个set()方法。get()方法将使用显式强制转换。

import java.util.Arrays;
class GenericArray<T>
{
    private Object[] genericArr;

    GenericArray(int size)
    {
        genericArr = new Object[size];
    }    
    public T get(int index)
    {
        return (T) genericArr[index];
    }    
    public void set(int index, T element)
    {
        genericArr[index] = element;
    }    
    @Override
    public String toString()
    {
        return Arrays.toString(genericArr);
    }
}
public class Demo
{
    public static void main(String[] args)
    {
        GenericArray<String> strArr = new GenericArray(3);
        strArr.set(0, "five");
        strArr.set(1, "ten");
        strArr.set(2, "twenty");        
        GenericArray<Integer> intArr = new GenericArray(3);
        intArr.set(0, 5);
        intArr.set(1, 10);
        intArr.set(2, 20);        
        GenericArray<Double> doubleArr = new GenericArray(3);
        doubleArr.set(0, 5.0);
        doubleArr.set(1, 10.0);
        doubleArr.set(2, 20.0);        
        System.out.println("Integer Array: " + intArr);
        System.out.println("String Array: " + strArr);
        System.out.println("Double Array: " + doubleArr);
    }
}

整数数组:[5,10,20] 字符串数组:[5,10,20] 双数组:[5.0,10.0,20.0]

如果我们只使用 get()和 set()方法,而不为用户提供对对象数组的直接访问,那么上述方法可以很好地工作。这里需要注意的一点是,即使是ArrayList也使用对象数组来存储元素。ArrayList不提供对此对象数组的直接访问。

使用反射创建通用数组

这种方法类似于上一节讨论的方法。唯一不同的是构造器会取类型信息,然后我们会用Array.newInstance()方法初始化我们的数组。完整的实现如下所示。

import java.lang.reflect.Array;
import java.util.Arrays;
class GenericArray<T>
{
    private T[] genericArr;

    GenericArray(Class<T> classType, int size)
    {
        genericArr = (T[]) Array.newInstance(classType, size);
    }    
    public T get(int index)
    {
        return genericArr[index];
    }    
    public void set(int index, T element)
    {
        genericArr[index] = element;
    }    
    @Override
    public String toString()
    {
        return Arrays.toString(genericArr);
    }
}
public class Demo
{
    public static void main(String[] args)
    {
        GenericArray<String> strArr = new GenericArray(String.class, 3);
        strArr.set(0, "five");
        strArr.set(1, "ten");
        strArr.set(2, "twenty");

        GenericArray<Integer> intArr = new GenericArray(Integer.class, 3);
        intArr.set(0, 5);
        intArr.set(1, 10);
        intArr.set(2, 20);

        GenericArray<Double> doubleArr = new GenericArray(Double.class, 3);
        doubleArr.set(0, 5.0);
        doubleArr.set(1, 10.0);
        doubleArr.set(2, 20.0);

        System.out.println("Integer Array: " + intArr);
        System.out.println("String Array: " + strArr);
        System.out.println("Double Array: " + doubleArr);
    }
}

整数数组:[5,10,20] 字符串数组:[5,10,20] 双数组:[5.0,10.0,20.0]

摘要

我们可以借助泛型类在 Java 中实现泛型数组。我们可以使用对象数组和适当的方法让用户与这个通用数组交互。ArrayList类也使用了对象数组的概念。我们还可以使用 Array.newInstance()方法,让用户将类型信息传递给构造器。一些集合的泛型方法也使用类似的方法,如 LinkedList。总的来说,建议使用ArrayListLinkedList来代替创建我们自己的通用列表。