2

假设我想通过默认构造函数创建一个长度为 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;
4

3 回答 3

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;
   }
于 2012-11-21T11:21:58.293 回答
2

您发布的代码的问题是 is 的擦除E[]Comparable[]因为E的上限是Comparable),因此强制转换其真实类型为Object[]to的对象Comparable[]将失败。

您可以简单地将其更改为以下内容,并且不会引发异常:

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


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

}

然而,这里还有更微妙的地方:myArrayis not really type E[]。在课堂内,E[]被擦除为Comparable[],所以没关系。但是你必须确保永远不要暴露myArray在课堂之外。由于它是私有的,您只需要确保没有方法返回它或其他东西。

这样做的好处是保持myArraytype E[],而不是 Jatin 对 using 的回答Comparable[],你不必每次从中得到一些东西时都进行强制转换,因此代码更好。

于 2012-11-21T20:46:42.283 回答
1

正如@Jatin 所指出的,如果你Object转换为,你会得到一个运行时异常,Comparable因为它是一个超级 for Comparable,因此不能转换为子类型。

如果可能,我建议您使用 anArrayList代替:

例如

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

     public A() {
         myArray = new ArrayList<E>(); 
     }    
}
于 2012-11-21T11:12:32.837 回答