[英]java generic casting in generic classes
I'm writing a simple implementation of a generic max heap. 我正在编写一个通用max堆的简单实现。 If I write
如果我写
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;
}
}
it compiles. 它编译。 Now to actually implement the heap, ie write maxHeapify(), I need to be able to compare two T's.
现在要实际实现堆,即编写maxHeapify(),我需要能够比较两个T。 One option that a priori seems possible would be to tell the compiler that T implements Comparable.
先验似乎可行的一种选择是告诉编译器T实现Comparable。 But if I type replace < T > with < T implements Comparable > the compiler complains -- how can I do this?
但是,如果我用<T实现Comparable>来替换<T>,编译器会抱怨-我该怎么做?
Alternatively, I could define a class 另外,我可以定义一个类
public class HasValue{
int value;
public HasValue(int value){
this.value = value;
}
} }
and in theory I should then be able to compare two HasValue objects like x.value > y.value. 从理论上讲,我应该能够比较两个HasValue对象,例如x.value> y.value。 But if I type
但是如果我输入
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;
}
}
I now get a ClassCastException. 我现在得到一个ClassCastException。 What is going on here?
这里发生了什么? Java generics hurt my brain.
Java泛型伤害了我的大脑。
In the first case T extends Object
which is erased to Object
at runtime. 在第一种情况下,
T extends Object
,该Object
在运行时被擦除为Object
。
In the second case T extends HasValue
is erased to HasValue
so you need to have. 在第二种情况下,
T extends HasValue
擦除为HasValue
因此您需要拥有。
data = (T[]) new HasValue[HEAP_SIZE];
IMHO It is needlessly pedantic that Java doesn't allow new T[HEAP_SIZE]
to do what you have to do anyway. 恕我直言,Java不允许
new T[HEAP_SIZE]
来做您必须做的事情,这是不必要的。
You may try this one (not compiled, yet) 您可以尝试这一步(尚未编译)
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;
}
}
It is better to have type token to create arrays like this 最好有类型标记来创建这样的数组
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;
}
}
In such way you will have no ClassCastExceptions in runtime 这样,您将在运行时没有ClassCastExceptions
And also: < T implements Comparable >
is not correct, correct one is < T extends Comparable >
而且:
< T implements Comparable >
不正确,正确的是< T extends Comparable >
Your heap should accept a Comparator< T > as a constructor argument. 您的堆应接受Comparator <T>作为构造函数参数。 Problem solved.
问题解决了。 Client can use any type he wants.
客户可以使用他想要的任何类型。 You can also supply a simple overload which infers the comparator implementation for types T that already implement Comparable.
您还可以提供一个简单的重载,它推断已经实现Comparable的T类型的比较器实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.