创建泛型类型的数组

时间:2012-11-21 10:59:36

标签: java generics wildcard

假设我想通过默认构造函数

创建一个长度为5的数组
public class A <E extends Comparable<? super E>> implements B<E>
{
     private E[] myArray;


     public A()
     {
         myArray = (E[]) new Object[5]; 
     }    

}

这是正确的做法吗?我很困惑,我是否必须这样做 在[]之前陈述“可比较”。所以

 private  Comparable[] myArray;

3 个答案:

答案 0 :(得分:4)

不。它将在运行时抛出ClassCastException

让我们看看原因。因为<E extends Comparable<? super E>>,一旦编译器删除了所有泛型类型,E将在整个类中被Comparable替换。

因此,在构造函数中,这是主要在运行时发生的事情:

 myArray =  new Comparable[5];

哪个是错的,因此也是例外。

它适用于class A <E> implements B<E>

所以解决方案是:

class A <E extends Comparable<? super E>> implements B<E>{
  Comparable[] array;
  public A(){
    array =  new Comparable[5];
   }
    @SuppressWarnings("unchecked")
   E get(int x)
   {
     return (E) array[x];
   }
   void add(E b){
     //for now
     array[0] = b;
   }

答案 1 :(得分:2)

您发布的代码的问题是E[]的删除是Comparable[](因为E的上限是Comparable),所以强制转换一个对象,实际类型为Object[]Comparable[]将失败。

您可以简单地将其更改为以下内容,它不会抛出异常:

public class A <E extends Comparable<? super E>> implements B<E>
{
     private E[] myArray;


     public A()
     {
         myArray = (E[]) new Comparable[5]; 
     }    

}

但是,这里有更多细微之处:myArray并非真正属于E[]类型。在课堂上,E[]被删除为Comparable[],所以没关系。但是你必须确保永远不要将myArray暴露给课外。由于它是私有的,你只需要确保没有方法返回它或什么。

这样做的好处是保持myArray类型E[],而不是Jatin使用Comparable[]的答案,就是每次你得到某些东西时都不需要施放出来,所以代码更好。

答案 2 :(得分:1)

正如@Jatin指出的那样,如果你将Object强制转换为Comparable,你会得到一个运行时异常,因为它是Comparable的超级,因此无法转换为子类型。

我建议您尽可能使用ArrayList

e.g。

public class A <E extends Comparable<? super E>> implements B<E> {
    private List<E> myArray;

     public A() {
         myArray = new ArrayList<E>(); 
     }    
}