What is the difference between 'super' and 'extends' in Java Generics [duplicate]
Asked Answered
D

6

92

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?

Designedly answered 15/12, 2009 at 22:30 Comment(3)
This has been discussed before - see #1368666 and https://mcmap.net/q/174759/-java-generics-wildcards and #1907177Dibb
(Note Comparable is a generic type, so using it as a raw type in a generic bound will cause misery. It should, at the very "simplest" be Comparable<?>.)Porphyritic
there is no "<T super Whatever>", only "<? super Whatever>"Actinic
T
16

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

Tonita answered 15/12, 2009 at 23:42 Comment(5)
This doesn't really explain how they work or what they mean, whereas R Samuel Klatchko's answer does.Schulein
Dont get it, doesn't explain the difference.Peper
This is how Bloch explains it: Suppose you want to add bulk methods to Stack<E>: •void pushAll(Collection<? extends E> src);void popAll(Collection<? super E> dst);User can pushAll from a Collection<Long> or a Collection<Number> onto a Stack<Number>User can popAll into a Collection<Object> or a Collection<Number> from a Stack<Number>Sitar
Producer? Consumer? Please explain. You're not answering the question.Peccadillo
It's nice that you like quoting Effective Java 2nd Edition, but the author has already mentioned he's searched around, implying he has seen this already. Anyway, his question wasn't when to use super vs extends, but what they actually mean. This implies he's looking for the mechanical difference between the two to gain understanding of the 'why' to use rather than the 'when' to use. This answer is at best tangential, but I think it's, rather, completely irrelevant to the question.Pleasant
P
300

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.

Physoclistous answered 15/12, 2009 at 22:53 Comment(4)
This is the best answer to this question I've ever seen, and ought to be the accepted answer. Simple and works perfectly.Schulein
So its more like down the inheritance (extends) or up the inheritance (super)Bolduc
<T super Parent > accepts either Parent or Grandparent, but how about Child? I just tried to add and it acceptsRibband
"<T super Parent> accepts either Parent or Grandparent" - and Object, right?Recursion
P
18

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.
Pernickety answered 15/12, 2009 at 22:57 Comment(2)
FYI: this is extracted from java.sun.com/developer/technicalArticles/J2SE/generics In the future please mention your sources instead of writing as if they're yours.Infringe
@BalusC's link to the article doesn't work anymore. Here's a current one: oracle.com/technetwork/articles/javase/generics-136597.htmlMan
T
16

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

Tonita answered 15/12, 2009 at 23:42 Comment(5)
This doesn't really explain how they work or what they mean, whereas R Samuel Klatchko's answer does.Schulein
Dont get it, doesn't explain the difference.Peper
This is how Bloch explains it: Suppose you want to add bulk methods to Stack<E>: •void pushAll(Collection<? extends E> src);void popAll(Collection<? super E> dst);User can pushAll from a Collection<Long> or a Collection<Number> onto a Stack<Number>User can popAll into a Collection<Object> or a Collection<Number> from a Stack<Number>Sitar
Producer? Consumer? Please explain. You're not answering the question.Peccadillo
It's nice that you like quoting Effective Java 2nd Edition, but the author has already mentioned he's searched around, implying he has seen this already. Anyway, his question wasn't when to use super vs extends, but what they actually mean. This implies he's looking for the mechanical difference between the two to gain understanding of the 'why' to use rather than the 'when' to use. This answer is at best tangential, but I think it's, rather, completely irrelevant to the question.Pleasant
S
16

For me the best answer came from @BSingh, when i read the article of Uncle Bob. I resume here, the conclusion of article.

Use List< T super Suit> whenever you are going to write into the list.

When you put an Object to the List, all you care about is that the object is of a type that is compatible with type held by the list. So you want the list to take the type of that object or any of the superclasses of that object.

Use List< T extends Suit> whenever you are going to read from a list.

On the other hand, when you read from a list, you want the type you are reading to be the type contained byt the list, or a derivative from that type.

Siusan answered 23/3, 2013 at 11:35 Comment(0)
D
5

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.

Dig answered 15/12, 2009 at 23:39 Comment(0)
S
3

Remember PECS - Producer Extends Consumer Support. Also, uncle Bob discusses it well in his craftsman series. Check out http://objectmentor.com/resources/articles/The_Craftsman_44__Brown_Bag_I.pdf

Spikes answered 16/12, 2009 at 0:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.