泛型类中的java泛型转换

时间:2012-12-19 20:27:00

标签: java generics casting

我正在编写一个通用最大堆的简单实现。如果我写

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

它编译。现在要实际实现堆,即写入maxHeapify(),我需要能够比较两个T。先验似乎可能的一个选择是告诉编译器T实现Comparable。但如果我输入replace&lt; T>与&lt; T实现Comparable&gt;编译器抱怨 - 我该怎么做?

或者,我可以定义一个类

public class HasValue{

  int value;

  public HasValue(int value){
        this.value = value;
  }

}

并且理论上我应该能够比较两个HasValue对象,例如x.value&gt; y.value。但如果我输入

public class FastMaxHeap<T extends HasValue>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

我现在得到一个ClassCastException。这里发生了什么? Java泛型伤害了我的大脑。

4 个答案:

答案 0 :(得分:5)

第一种情况T extends Object在运行时被删除为Object

在第二种情况下,T extends HasValue被删除为HasValue,因此您需要拥有。{/ p>

data = (T[]) new HasValue[HEAP_SIZE];

恕我直言,Java不允许new T[HEAP_SIZE]做你必须做的事情,这是不必要的迂腐。

答案 1 :(得分:0)

您可以尝试这个(尚未编译)

public class FastMaxHeap<T extends HasValue>{

  HasValue[] data;
  int size;

  static final int HEAP_SIZE = 10000;

   public FastMaxHeap(){
     data = new HasValue[HEAP_SIZE];
     size = 0;
   }
}

答案 2 :(得分:0)

最好让类型令牌来创建像这样的数组

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(Class<T> clazz){
    data = (T[])Array.newInstance(clazz, HEAP_SIZE);
    size = 0;
  }
}

以这种方式,你在运行时没有ClassCastExceptions

而且:< T implements Comparable >不正确,正确的是< T extends Comparable >

答案 3 :(得分:0)

你的堆应该接受比较器&lt; T>作为构造函数的参数。问题解决了。客户可以使用他想要的任何类型。您还可以提供一个简单的重载,它可以推断已经实现Comparable的类型T的比较器实现。