What is the difference between 'super' and 'extends' in Java Generics

Viewed 42710

I am trying to learn Java generics. I am not clear when you will use <T extends Foo> and when you will use <T super Foo>. What do each one of these things mean about T? Lets say I have <T extends Comparable> and <T super Comparable>, what do each of these mean?

I've read several tutorials at sun.com but I'm still lost. Can somebody illustrate with examples?

6 Answers

It depends which way on the inheritance hierarchy it allows. Assume you have a class "Child" which inherits from "Parent" which inherits from "Grandparent".

<T extends Parent> accepts either Parent or Child while <T super Parent> accepts either Parent or Grandparent.

There are three types of wildcards:

  • ? extends Type: Denotes a family of subtypes of type Type. This is the most useful wildcard.
  • ? super Type: Denotes a family of supertypes of type Type.
  • ?: Denotes the set of all types or any.

See Effective Java 2nd Edition, Item 28:

PECS

Producer extends, Consumer super

If your parameter is a producer, it should be <? extends T>, if it's a consumer it has to be <? super T>.

Take a look at the Google Collections, they know how to use it, because they got Bloch ;)

If you are asking about type parameters, then there is no <T super X> construct in Java. Bounded parameter can only extend, but it can extend more than one type. E.g

public class MyClass< T extends Closeable & Runnable >
{
  // Closeable and Runnable are chosen for demonstration purposes only
}

In this case if you see MyClass< ConcreteT > then ConcreteT must be declared as

public class ConcreteT
  implements Closeable, Runnable
{
   ...
}

For bounded wildcards, read this article. Read section on get-put principle. Basically, super corresponds to write semantics, and extends corresponds to read semantics.

Related