[英]How to initialize a generic array containing generics?
我有以下代码:
public class I<T> {
private T t;
public I(T t) {
this.t=t;
}
}
public class G<T> {
private I<T> tab[];
public G() {
tab=(I<T>[]) new Object[10];
}
}
调用 G() 会抛出 ClassCastException。
我如何编写 G 构造函数以初始化选项卡?
tab=(I<T>[]) new I<?>[10];
是答案,但对我来说仍然很神秘!
希望揭开你自己的答案的神秘面纱:请注意,java 通过擦除实现泛型,即编译器基本上会进行一些编译时检查,然后丢弃泛型。
因此,从运行时的角度来看,您的第一种方法归结为:
I[] tab = (I[]) new Object[10];
由于数组类型是真正区分的类,因此您会在此处获得类转换异常,因为 I[].class 与 Object[].class 不同。
您的第二种方法是(放弃泛型):
I[] tab = (I[]) new I[10];
...这里没有问题。
Tab 是一个 I 的数组。I 是一个 Object,但是new Object()
创建的一个简单的 Object不是I。这就解释了为什么第一种方法会产生错误。 您必须创建一个 I 数组来初始化tab
。
但这还不是全部:java 泛型使用类型擦除。 这意味着在运行时编译器不知道 T 是什么。 tab = new I<T>[10];
当 T 不再有意义时在运行时执行,因此错误。
解决方案是创建一个I数组( new I<?>
)或一个I<Object>
数组,甚至使用旧的(前通用)语法new I[10]
。
这里没有问,但是当你真的需要知道泛型中参数的类型时,常见的习惯用法是在构造函数或 setter 中显式传递类,以便泛型对象可以使用它。 代码可以是:
class G<T> {
private I<T> tab[];
private Class<T> clazz;
...
public G(Class<T> clazz) {
this.clazz = clazz;
tab = new I[10];
// here we can use the type of T from clazz by reflexion...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.