问题
My question is about generics in Java 7. Suppose we have such class hierarchy:
interface Animal {}
class Lion implements Animal {}
class Butterfly implements Animal {}
Just like in Java Generics Tutorial
Also we have a class
class Cage<T> {
private List<T> arr = new ArrayList<>();
public void add(T t) {
arr.add(t);
}
public T get() {
return arr.get(0);
}
}
And here is the code which uses that classes:
public static void main(String[] args) {
Cage<? extends Animal> cage = new Cage<>();
Animal a = cage.get(); //OK
cage.add(new Lion()); //Compile-time error
cage.add(new Butterfly()); //Compile-time error
}
Question #1:
I have read here about these issues but there was simply like Cage<?>
. But I tell the compiler <? extends Animal>
so type T
in Cage<T>
will be any of subtypes of Animal type. So why it still gives a compile time error?
Question #2:
If I specify Cage<? super Animal> cage = ...
instead of Cage<? extends Animal> cage = ...
everything works fine and compiler doesn't say anything bad. Why in this case it works fine while in the example above it fails?
回答1:
The cage must be able to hold both types of animals. "super" says that - it says that the Cage must be able to hold all types of animals - and maybe some other things, too, because ? super Animal
might be a superclass of Animal. "extends" says that it can hold some kinds of animals - maybe just Lions, for instance, as in:
Cage<? extends Animal> cage = new Cage<Lion>();
which would be a valid statement, but obviously the lion cage won't hold butterflies, so
cage.add(new Butterfly());
wouldn't compile. The statement
cage.add(new Lion());
wouldn't compile either, because Java here is looking at the declaration of the cage - Cage<? extends Animal>
- not the object that's assigned to it right now (Cage<Lion>
).
The best description of generics I know of is in O'Reilly's Java in a Nutshell. The chapter is free online - part 1 and part 2.
来源:https://stackoverflow.com/questions/7541849/wildcards-in-generics-super-t-works-while-extends-t-does-not