Java不允许我们这么做的原因是什么
private T[] elements = new T[initialCapacity];
我可以理解。net不允许我们这样做,因为在。net中,值类型在运行时可以有不同的大小,但在Java中,所有类型的T都将是对象引用,因此具有相同的大小(如果我错了请纠正我)。
原因是什么?
Java不允许我们这么做的原因是什么
private T[] elements = new T[initialCapacity];
我可以理解。net不允许我们这样做,因为在。net中,值类型在运行时可以有不同的大小,但在Java中,所有类型的T都将是对象引用,因此具有相同的大小(如果我错了请纠正我)。
原因是什么?
当前回答
如果我们不能实例化泛型数组,为什么语言有泛型数组类型?没有对象的类型有什么意义呢?
我能想到的唯一原因是varargs - foo(T…)。否则,它们可以完全删除泛型数组类型。(好吧,他们真的不需要为可变参数使用数组,因为在1.5之前不存在可变参数。这可能是另一个错误。)
所以这是一个谎言,你可以实例化泛型数组,通过varargs!
当然,泛型数组的问题仍然存在,例如。
static <T> T[] foo(T... args){
return args;
}
static <T> T[] foo2(T a1, T a2){
return foo(a1, a2);
}
public static void main(String[] args){
String[] x2 = foo2("a", "b"); // heap pollution!
}
我们可以用这个例子来实际演示泛型数组的危险。
另一方面,我们已经使用泛型变参数10年了,现在还没有崩溃。所以我们可以说问题被夸大了;这没什么大不了的。如果允许显式的泛型数组创建,我们会到处都有bug;但我们已经习惯了擦除的问题,我们可以接受它。
我们可以用foo2来反驳这种说法,即规范让我们避免了他们声称让我们避免的问题。如果Sun在1.5上有更多的时间和资源,我相信他们可以达成一个更令人满意的解决方案。
其他回答
肯定有一个好方法(可能是使用反射),因为在我看来,这正是数组列表。toArray(T[] a)可以。我引用:
public <T> T[] toArray(T[] a) 返回一个数组,其中包含所有 此列表中的元素按正确顺序排列;的运行时类型 返回的数组是指定数组的数组。如果列表符合 指定的数组,则在其中返回。否则,新数组为 的运行时类型分配 这个列表。
因此,一种方法是使用这个函数,即创建一个数组中你想要的对象的数组列表,然后使用toArray(T[] a)来创建实际的数组。不会很快,但你没提你的要求。
有人知道toArray(T[] a)是如何实现的吗?
T vals [];/ /好吧
但是,你不能实例化T的数组 // vals = new T[10];//不能创建T的数组
你不能创建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中创建泛型数组类型。我误解了这个问题吗?
在我的例子中,我只是想要一个堆栈数组,就像这样:
Stack<SomeType>[] stacks = new Stack<SomeType>[2];
由于这是不可能的,我使用了以下作为解决方案:
创建一个非泛型包装器类围绕堆栈(例如MyStack) MyStack[] stacks = new MyStack[2]工作得很好
丑陋,但Java是快乐的。
注意:正如BrainSlugs83在问题的评论中提到的,在.NET中完全可以有泛型数组
答案已经给出了,但如果你已经有一个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