如何在Java中创建一个类型变量的数组?

4
在Java中,可以声明一个类型变量的数组,但是我无法创建该数组。这是不可能的吗?
class ClassName<T> {
    {
        T[] localVar; // OK
        localVar = new T[3]; // Error: Cannot create a generic array of T
    }
}

已添加到FAQ - finnw
6个回答

5

Java中没有泛型数组,您可以使用ArrayList。

解释:

Java中的数组是协变类型。Java数组具有协变类型的特性,这意味着超类型引用的数组是子类型引用数组的超类型。也就是说,例如,Object []String []的超类型。由于协变性,所有常规的子类型和超类型适用的类型规则都适用:子类型数组可以分配给超类型数组变量,子类型数组可以作为期望超类型数组的参数传递给方法,等等。以下是示例:

Object[] objArr = new String[10];// fine

相比之下,泛型集合不具备协变性。对于超类型的参数化类型实例化不被认为是子类型的参数化类型实例化的超类型。也就是说,LinkedList<Object> 不是 LinkedList<String> 的超类型,因此不能在期望 LinkedList<Object> 的地方使用 LinkedList<String>,这两个相同参数化类型的实例化之间不存在赋值兼容性等。以下是一个说明差异的示例:
LinkedList<Object> objLst = new LinkedList<String>(); // compile-time error

来源:http://www.angelikalanger.com/Articles/Papers/JavaGenerics/ArraysInJavaGenerics.htm

这篇文章是关于Java中泛型数组的问题。在Java中,如果要使用泛型数组,需要特别小心,因为Java不支持泛型数组。通常情况下,我们需要使用容器类来代替泛型数组。但是,有时候我们仍然需要使用数组,那么该怎么办呢?本文将介绍如何通过强制转换和类型擦除来处理泛型数组的问题。


3
T[] localVar = (T[])(new Vector<T>(3).toArray()); // new T[3];

2

只有在具有实例化泛型的语言中才能实现这一点,比如Gosu。Java使用类型擦除,因此T的类型在运行时不可用。


1

不行。如果你有代表 TClass 对象,你可以使用 java.lang.reflect.Array 来实现:

public static <T> T[] createArray(Class<T> clazz, int size) {
    T[] array = (T[]) java.lang.reflect.Array.newInstance(clazz, length);
    return array;
}

0
另一种解决方法是创建一个不同的类来保存类型变量,然后创建该类的数组。例如:
    public class test<T>{
        data[] localVar = new data[1];
        private class data<E>{
            E info;
            public data(E e){ info = e; }
        }
        public void add(T e){ localVar[0] = new data<T>(e); }
    }

上面的代码除非你想向数组中添加一个项目,否则无法用于任何实际用途,但它只是展示了这个想法。


0

你不能直接初始化一个泛型类型。但是,你可以创建一个 Object 类型的数组,并将其转换为泛型数组类型,如下所示:

class ClassName<T> {
    {
        T[] localVar = (T[]) new Object[3];
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接