Java不允许我们这么做的原因是什么

private T[] elements = new T[initialCapacity];

我可以理解。net不允许我们这样做,因为在。net中,值类型在运行时可以有不同的大小,但在Java中,所有类型的T都将是对象引用,因此具有相同的大小(如果我错了请纠正我)。

原因是什么?


当前回答

这是因为泛型是在他们创建后才添加到java的,所以它有点笨拙,因为java的原始创造者认为在创建数组时,类型应该在创建时指定。这对泛型不起作用,所以你必须这么做 E[] array=(E[]) new Object[15]; 这将编译,但会给出警告。

其他回答

在我看来,如果你不能提供一个像样的解决方案,你只会落得更糟糕的结果。

常见的工作方法如下。

T[] ts = new T[n];

替换为(假设T扩展Object而不是其他类)

T[] ts = (T[]) new Object[n];

我更喜欢第一个例子,然而更多的学院派似乎更喜欢第二个例子,或者干脆不去想它。

关于为什么不能只使用Object[]的大多数例子都适用于List或Collection(它们都是受支持的),所以我认为它们是非常糟糕的参数。

注意:这是Collections库本身不会在没有警告的情况下编译的原因之一。如果在没有警告的情况下不能支持这个用例,那么恕我直言,泛型模型从根本上就有问题了。

肯定有一个好方法(可能是使用反射),因为在我看来,这正是数组列表。toArray(T[] a)可以。我引用:

public <T> T[] toArray(T[] a) 返回一个数组,其中包含所有 此列表中的元素按正确顺序排列;的运行时类型 返回的数组是指定数组的数组。如果列表符合 指定的数组,则在其中返回。否则,新数组为 的运行时类型分配 这个列表。

因此,一种方法是使用这个函数,即创建一个数组中你想要的对象的数组列表,然后使用toArray(T[] a)来创建实际的数组。不会很快,但你没提你的要求。

有人知道toArray(T[] a)是如何实现的吗?

这是因为Java的数组(与泛型不同)在运行时包含关于其组件类型的信息。因此,在创建数组时必须知道组件类型。因为您不知道T在运行时是什么,所以您不能创建数组。

我喜欢间接给出的答案 Gafter。然而,我认为这是错误的。我稍微修改了一下加福特的代码。它编译并运行一段时间,然后在Gafter预测的地方爆炸

class Box<T> {

    final T x;

    Box(T x) {
        this.x = x;
    }
}

class Loophole {

    public static <T> T[] array(final T... values) {
        return (values);
    }

    public static void main(String[] args) {

        Box<String> a = new Box("Hello");
        Box<String> b = new Box("World");
        Box<String> c = new Box("!!!!!!!!!!!");
        Box<String>[] bsa = array(a, b, c);
        System.out.println("I created an array of generics.");

        Object[] oa = bsa;
        oa[0] = new Box<Integer>(3);
        System.out.println("error not caught by array store check");

        try {
            String s = bsa[0].x;
        } catch (ClassCastException cause) {
            System.out.println("BOOM!");
            cause.printStackTrace();
        }
    }
}

输出为

I created an array of generics.
error not caught by array store check
BOOM!
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at Loophole.main(Box.java:26)

在我看来,你可以在java中创建泛型数组类型。我误解了这个问题吗?

答案已经给出了,但如果你已经有一个T的实例,那么你可以这样做:

T t; //Assuming you already have this object instantiated or given by parameter.
int length;
T[] ts = (T[]) Array.newInstance(t.getClass(), length);

希望,我能帮忙, Ferdi265