【发布时间】:2017-04-02 19:48:22
【问题描述】:
我发现如果你有一个泛型类,其数组依赖于该类的类型参数,你不能以通常的方式初始化该数组:
class Foo<T> {
private T[] a;
Foo() {
a=new T[5]; //doesn't compile
}
}
你只能这样做:
class Foo<T> {
private T[] a;
Foo(T[] a) {
this.a=a;
}
}
但是这个代码是可能的:
ArrayList<Integer> list=new ArrayList<>();
为什么? ArrayList 是如何克服这个问题的?我查看了它的代码,但无法弄清楚。它似乎只是将东西存储在 Object[] 数组中,这似乎是错误的。
【问题讨论】:
-
如果错了,ArrayList 会起作用。但它有效。所以没有错。为什么你认为这是错误的?
-
@JB Nizet,因为即使没有泛型我们也可以做到这一点,在内部使用
Object[]有什么意义。泛型的用处不在于可以精确存储类型T吗? -
由于
T在编译时被擦除,因此代码new T[size]需要编译为new Object[size],这让我们拥有能够保存any 对象的数组。但在第二种情况下,编译器能够检测我们是否传递数组已经存在并且它的类型匹配指定的T类型。 -
@parsecer 泛型在运行时被删除,这使得 new T[] 不可能。但是您不应该关心内部数组的类型,因为它是私有的,因此不是公共 API 的一部分。重要的是列表是类型安全的,并且编译器会阻止将字符串添加到 List
。列表内部存储 Integer 的位置和方式无关紧要。