2016-05-13 58 views
1

我有以下代码:如何初始化包含泛型的泛型数组?

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构造函数才能初始化选项卡?

回答

1
tab=(I<T>[]) new I<?>[10]; 

是答案,但它对我来说依然神秘!

0

为了让你自己的回答有点神秘:请注意,Java通过擦除来实现泛型,即编译器基本上会执行一些编译时检查,然后丢弃泛型。

所以,从运行时间来看,你的第一种方法可以归结为:

I[] tab = (I[]) new Object[10]; 

由于数组类型是真正杰出的课程,你会得到一个类转换异常在这里,因为我[]类。与Object []。类不一样。

你的第二个方法是(丢弃仿制药):

I[] tab = (I[]) new I[10]; 

...这里没有问题。

+0

你可以提供一个链接,了解这个人 – emotionlessbananas

+0

检查教程线索在https://docs.oracle.com/javase/tutorial/java/generics/erasure.html – mtj

+0

感谢链接 – emotionlessbananas

0

Tab是我。我的数组是一个对象,而是通过new Object()创建了一个简单的对象是一个一,这解释了为什么第一种方式产生的错误。您必须创建一个数组来初始化tab

但这并非全部:java泛型使用类型擦除。那意味着在运行时编译器不知道T是什么。当T不再有任何意义时,运行时执行tab = new I<T>[10];,因此是错误。

的解决方案是创建的任何(​​)我的阵列或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... 
    } 
}