tnk_peka
tnk_peka

Reputation: 1535

Java generic usage error

The code below uses simple generics and compiles correctly. When I try to create a object of type McDelayQueue, I get an error.

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);
        }
    }
}

and this is an 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;
    }
}

But when I try to create an instance:

  McDelayQueue<DelayQueryKey<String>, String> delayQueryKeys = new McDelayQueue();

I get this compile-time error:

Error:(14, 69) java: type argument pubsub.delayqueue.custom.DelayQueryKey<java.lang.String> is not within bounds of type-variable E !!

What's wrong here?

Upvotes: 0

Views: 231

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280171

You're using the raw IValue type in your DelayQueryKey class definition

class DelayQueryKey<T> implements Delayed, IValue {

DelayQueryKey<String> therefore doesn't fit the bounds set out by

McDelayQueue<E extends Delayed & IValue<K>, K>

Instead, parametrize it (appropriately)

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

Although not necessary in this case, develop the habit of providing type arguments (diamond operator or otherwise) to constructor invocations that require them

new McDelayQueue<>();

Upvotes: 3

Related Questions