Java 一般使用错误
Java generic usage error
下面的代码使用简单的泛型并正确编译。当我尝试创建 McDelayQueue
类型的对象时,出现错误。
public class McDelayQueue<E extends Delayed & IValue<K>, K> extends DelayQueue<E> {
final Set keys = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());
@Override
public E take() throws InterruptedException {
E data = super.take();
final K key = data.getKey();
keys.remove(key);
return data;
}
@Override
public void put(E e) {
if (!keys.contains(e.getKey())) {
keys.add(e);
super.put(e);
}
}
}
这是一个 E class :
public class DelayQueryKey<T> implements Delayed, IValue {
private T key;
private long startTime;
public DelayQueryKey(T key, long delay) {
this.key = key;
this.startTime = System.currentTimeMillis() + delay;
}
@Override
public long getDelay(TimeUnit unit) {
long diff = startTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MINUTES);
}
@Override
public int compareTo(Delayed o) {
if (this.startTime < ((DelayQueryKey) o).startTime) {
return -1;
}
if (this.startTime > ((DelayQueryKey) o).startTime) {
return 1;
}
return 0;
}
@Override
public String toString() {
return "{" +
"key='" + key + '\'' +
", startTime=" + startTime +
'}';
}
public T getKey() {
return key;
}
}
但是当我尝试创建实例时:
McDelayQueue<DelayQueryKey<String>, String> delayQueryKeys = new McDelayQueue();
我得到这个编译时错误:
Error:(14, 69) java: type argument pubsub.delayqueue.custom.DelayQueryKey<java.lang.String> is not within bounds of type-variable E !!
这是怎么回事?
您在 DelayQueryKey
class 定义中使用原始 IValue
类型
class DelayQueryKey<T> implements Delayed, IValue {
DelayQueryKey<String>
因此不符合
设定的界限
McDelayQueue<E extends Delayed & IValue<K>, K>
相反,对其进行参数化(适当地)
class DelayQueryKey<T> implements Delayed, IValue<T> {
虽然在这种情况下没有必要,但养成向需要它们的构造函数调用提供类型参数(菱形运算符或其他方式)的习惯
new McDelayQueue<>();
下面的代码使用简单的泛型并正确编译。当我尝试创建 McDelayQueue
类型的对象时,出现错误。
public class McDelayQueue<E extends Delayed & IValue<K>, K> extends DelayQueue<E> {
final Set keys = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());
@Override
public E take() throws InterruptedException {
E data = super.take();
final K key = data.getKey();
keys.remove(key);
return data;
}
@Override
public void put(E e) {
if (!keys.contains(e.getKey())) {
keys.add(e);
super.put(e);
}
}
}
这是一个 E class :
public class DelayQueryKey<T> implements Delayed, IValue {
private T key;
private long startTime;
public DelayQueryKey(T key, long delay) {
this.key = key;
this.startTime = System.currentTimeMillis() + delay;
}
@Override
public long getDelay(TimeUnit unit) {
long diff = startTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MINUTES);
}
@Override
public int compareTo(Delayed o) {
if (this.startTime < ((DelayQueryKey) o).startTime) {
return -1;
}
if (this.startTime > ((DelayQueryKey) o).startTime) {
return 1;
}
return 0;
}
@Override
public String toString() {
return "{" +
"key='" + key + '\'' +
", startTime=" + startTime +
'}';
}
public T getKey() {
return key;
}
}
但是当我尝试创建实例时:
McDelayQueue<DelayQueryKey<String>, String> delayQueryKeys = new McDelayQueue();
我得到这个编译时错误:
Error:(14, 69) java: type argument pubsub.delayqueue.custom.DelayQueryKey<java.lang.String> is not within bounds of type-variable E !!
这是怎么回事?
您在 DelayQueryKey
class 定义中使用原始 IValue
类型
class DelayQueryKey<T> implements Delayed, IValue {
DelayQueryKey<String>
因此不符合
McDelayQueue<E extends Delayed & IValue<K>, K>
相反,对其进行参数化(适当地)
class DelayQueryKey<T> implements Delayed, IValue<T> {
虽然在这种情况下没有必要,但养成向需要它们的构造函数调用提供类型参数(菱形运算符或其他方式)的习惯
new McDelayQueue<>();