[英]java generic casting in generic classes
我正在编写一个通用max堆的简单实现。 如果我写
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。 但是,如果我用<T实现Comparable>来替换<T>,编译器会抱怨-我该怎么做?
另外,我可以定义一个类
public class HasValue{
int value;
public HasValue(int value){
this.value = value;
}
}
从理论上讲,我应该能够比较两个HasValue对象,例如x.value> 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泛型伤害了我的大脑。
在第一种情况下, T extends Object
,该Object
在运行时被擦除为Object
。
在第二种情况下, T extends HasValue
擦除为HasValue
因此您需要拥有。
data = (T[]) new HasValue[HEAP_SIZE];
恕我直言,Java不允许new T[HEAP_SIZE]
来做您必须做的事情,这是不必要的。
您可以尝试这一步(尚未编译)
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;
}
}
最好有类型标记来创建这样的数组
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 >
您的堆应接受Comparator <T>作为构造函数参数。 问题解决了。 客户可以使用他想要的任何类型。 您还可以提供一个简单的重载,它推断已经实现Comparable的T类型的比较器实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.