Java通用用法错误

时间:2015-06-16 03:22:08

标签: java collections generics

下面的代码使用简单的泛型并正确编译。当我尝试创建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类:

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 !!

这里有什么问题?

1 个答案:

答案 0 :(得分:3)

您在IValue班级定义

中使用原始DelayQueryKey类型
class DelayQueryKey<T> implements Delayed, IValue {
因此,

DelayQueryKey<String>不符合

规定的范围
McDelayQueue<E extends Delayed & IValue<K>, K>

相反,参数化(适当地)

class DelayQueryKey<T> implements Delayed, IValue<T> {

虽然在这种情况下没有必要,但养成为需要它们的构造函数调用提供类型参数(菱形运算符或其他)的习惯

new McDelayQueue<>();