繁体   English   中英

如何初始化包含泛型的泛型数组?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM