3

Here are two forms to work with generics extending base type:

public abstract <T extends Runnable> BlockingQueue<T> getQueueA();
public abstract BlockingQueue<? extends Runnable> getQueueB();

I don't understand. What is the difference? Both methods seem to return the same BlockingQueue of objects that extend Runnable.

Ryan Ransford
  • 3,224
  • 28
  • 35
Andrey
  • 853
  • 9
  • 27

2 Answers2

3
BlockingQueue<Thread> threads = thing.getQueueA(); // works

BlockingQueue<Thread> threads = thing.getQueueB(); // does not work

On the other side of things:

@Override public <T extends Runnable> BlockingQueue<T> getQueueA() {
    return new ArrayBlockQueue<Thread>(); // no worky
}
@Override public BlockingQueue<? extends Runnable> getQueueB() {
    return new ArrayBlockQueue<Thread>(); // works
}
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
2

Although both return queues of a type that extends Runnable, the difference is that the first version is a typed method, and the type T is available inside the method and to the compiler so it may infer the type when the method is called.

The second version has none of these benefits: it merely returns a queue whose type is unknown, but extends Runnable.

Bohemian
  • 412,405
  • 93
  • 575
  • 722