我发现如果你有一个泛型类,其数组依赖于该类的类型参数,则无法以通常的方式初始化该数组:
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[]
数组中,这似乎是错误的。
答案 0 :(得分:3)
ArrayList
内的数组始终为Object[]
类型,因为您可以将任何内容存储在此类数组中。类型参数在方法级别上启用类型安全,这是重要的。
编辑以按要求解决类型擦除主题:
Java中的类型擦除意味着泛型类型参数仅在编译期间出现,其中最重要的是确保类型安全。泛型已经通过这种方式实现,以保持较新版本的Java与旧版本兼容。
这样做的缺点是永远不能实例化泛型类型,因为它在运行时永远不会被人知道。
答案 1 :(得分:2)
将此视为一个类比:
你拥有一家铅笔公司。你在车里用铅笔开车。
你可以把鲜花放在你的面包车里:毕竟它是一辆面包车,所以你可以把任何你想要的东西放在那里。棒球,大猩猩,氦气球。
但你选择不这样做:你是一家铅笔公司,所以你把它放进你的货车里就是铅笔。如果您的汉堡公司的朋友要求您在面包车上放一些汉堡肉饼,您会拒绝:这辆面包车只适用于铅笔。
所以,当你从你的面包车里取出一些东西时,你知道它会成为一支铅笔,因为你确保通过那些门进入的唯一东西就是铅笔。
所以它是ArrayList<T>
:你可以存储Object[]
中的任何内容,但你不能:你只能存储T
在那里,因为你只能通过add(T)
或addAll(Collection<? extends T>)
方法向它添加内容。
因此,将您的元素存储在Object[]
而不是更具体的类型数组中并不重要:您将从{{1}中获得的唯一内容} - 通过其ArrayList<T>
(等)方法 - 是get()
或其子类型之一的实例。