I am reading the Core Java (9th edition) by Cay S. Horstmann and Gary Cornell. After making an effort, I cannot still understand the ? super Manager. Here are some materials relating to this question.
public class Pair<T> {
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public void setFirst(T first) {
this.first = first;
}
public void setSecond(T second) {
this.second = second;
}
public T getFrist() {
return this.first;
}
public T getSecond() {
return this.second;
}
}
The Manager inherits from Employee, and Executive inherites from Manager. Pair has methods as follows:
void setFirst(? super Manager)
? super Manager getFirst()
Since ? super Manager denotes any supertype of Manager, why I cannot call setFirst method with Employee (it is obvious that Employee is the supertype of Manager), but only with type Manager or a subtype such as Executive(but Executive is the subtype of Manager, not a supertype of Manager)?
Best Answer
One can read and re-iterate it over and over again - as it has been many times already. In a comment to your question, Philipp already linked to a question on Stackoverflow which tries to answer it. For me, the explanation of Uncle Bob did the trick.
He writes (next to a lot of other good stuff):
What this means in the end is that your assumption you'd be able to put super-types of
Manager
into yourList<? super Manager>
is wrong. That's not what is meant here. Thesuper
keyword solves the problem of not being able to insert stuff into generic places while you were able to get some out (withextends
).Imagine two pairs, one that extends Manager, one that "supers" it:
What you can never do, is insert an
Employee
in any of these:If you want managers, employees will never be enough. And it's worse: you can't even insert an
Executive
into yoursubPair
, even thoughExecutive extends Manager
. It won't compile either:Edit: Why is that? Well, your generic
subPair
always refers to some "explicit"Pair
,Pair<Manager>
in this case. It just as well might have referred to aPair<CoManager>
(withCoManager extends Manager
). Java won't know the explicit type that's actually used and thus can't allow you insertions.But
super
comes to the rescue. Withsuper
you can insert Managers and their sub-types into yourPair
. And that is whatsuper
is for: Inserting.Edit: Any why does that work? While
extends
guarantees you some type that implements (or derives from)Manager
,super
guarantees you any such type. So, while withextends
you get a specific type with (at least) theManager
interface, withsuper
you can insert any type with theManager
interface.And for the bigger picture, I really suggest reading the article of Uncle Bob.