Java不允许我们这么做的原因是什么
private T[] elements = new T[initialCapacity];
我可以理解。net不允许我们这样做,因为在。net中,值类型在运行时可以有不同的大小,但在Java中,所有类型的T都将是对象引用,因此具有相同的大小(如果我错了请纠正我)。
原因是什么?
Java不允许我们这么做的原因是什么
private T[] elements = new T[initialCapacity];
我可以理解。net不允许我们这样做,因为在。net中,值类型在运行时可以有不同的大小,但在Java中,所有类型的T都将是对象引用,因此具有相同的大小(如果我错了请纠正我)。
原因是什么?
当前回答
肯定有一个好方法(可能是使用反射),因为在我看来,这正是数组列表。toArray(T[] a)可以。我引用:
public <T> T[] toArray(T[] a) 返回一个数组,其中包含所有 此列表中的元素按正确顺序排列;的运行时类型 返回的数组是指定数组的数组。如果列表符合 指定的数组,则在其中返回。否则,新数组为 的运行时类型分配 这个列表。
因此,一种方法是使用这个函数,即创建一个数组中你想要的对象的数组列表,然后使用toArray(T[] a)来创建实际的数组。不会很快,但你没提你的要求。
有人知道toArray(T[] a)是如何实现的吗?
其他回答
这是不可能的,因为Java完全在编译器级别上实现了泛型,并且每个类只生成一个类文件。 这叫做类型擦除。
在运行时,已编译的类需要用相同的字节码处理它的所有使用。因此,new T[capacity]将完全不知道需要实例化什么类型。
引用:
Arrays of generic types are not allowed because they're not sound. The problem is due to the interaction of Java arrays, which are not statically sound but are dynamically checked, with generics, which are statically sound and not dynamically checked. Here is how you could exploit the loophole: class Box<T> { final T x; Box(T x) { this.x = x; } } class Loophole { public static void main(String[] args) { Box<String>[] bsa = new Box<String>[3]; Object[] oa = bsa; oa[0] = new Box<Integer>(3); // error not caught by array store check String s = bsa[0].x; // BOOM! } } We had proposed to resolve this problem using statically safe arrays (aka Variance) bute that was rejected for Tiger. -- gafter
(我相信是尼尔·盖特,但不确定)
在这里查看上下文:http://forums.sun.com/thread.jspa?threadID=457033&forumID=316
在我看来,如果你不能提供一个像样的解决方案,你只会落得更糟糕的结果。
常见的工作方法如下。
T[] ts = new T[n];
替换为(假设T扩展Object而不是其他类)
T[] ts = (T[]) new Object[n];
我更喜欢第一个例子,然而更多的学院派似乎更喜欢第二个例子,或者干脆不去想它。
关于为什么不能只使用Object[]的大多数例子都适用于List或Collection(它们都是受支持的),所以我认为它们是非常糟糕的参数。
注意:这是Collections库本身不会在没有警告的情况下编译的原因之一。如果在没有警告的情况下不能支持这个用例,那么恕我直言,泛型模型从根本上就有问题了。
Oracle教程:
You cannot create arrays of parameterized types. For example, the following code does not compile: List<Integer>[] arrayOfLists = new List<Integer>[2]; // compile-time error The following code illustrates what happens when different types are inserted into an array: Object[] strings = new String[2]; strings[0] = "hi"; // OK strings[1] = 100; // An ArrayStoreException is thrown. If you try the same thing with a generic list, there would be a problem: Object[] stringLists = new List<String>[]; // compiler error, but pretend it's allowed stringLists[0] = new ArrayList<String>(); // OK stringLists[1] = new ArrayList<Integer>(); // An ArrayStoreException should be thrown, // but the runtime can't detect it. If arrays of parameterized lists were allowed, the previous code would fail to throw the desired ArrayStoreException.
对我来说,这听起来很软弱。我认为任何对泛型有充分理解的人,都完全可以理解,甚至期望,在这种情况下ArrayStoredException不会被抛出。
答案已经给出了,但如果你已经有一个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