I\'d never heard about wildcars until a few days ago and after reading my teacher\'s Java book, I\'m still not sure about what\'s it for and why would I need to use it.
You can store Dogs and Cats in a List<Animal>
. That is not where wildcards are needed.
Let's say you have a method that takes a list of animals:
void foo(List<Animal> animals) {
...
}
Now you can't pass the method a List of Dogs -- it only takes an argument of type List<Animal>
. You need a wildcard to make the method accept all kinds of Lists of Animals: List<Animal>
, List<Dog>
, List<Cat>
, ...
void foo(List<? extends Animal> animals) {
...
}
See
http://java.sun.com/docs/books/tutorial/extra/generics/wildcards.html
The wildcards do not make a lot of sense when you declare local variables, however they are really important when you declare a parameter for a method.
Imagine you have a method:
int countLegs ( List< ? extends Animal > animals )
{
int retVal = 0;
for ( Animal cur : animals )
{
retVal += cur.countLegs( );
}
return retVal;
}
With this signature you can do this:
List<Dog> dogs = ...;
countLegs( dogs );
List<Cat> cats = ...;
countLegs( cats );
List<Animal> zoo = ...;
countLegs( zoo );
If, however, you declare countLegs
like this:
int countLegs ( List< Animal > animals )
Then in the previous example only countLegs( zoo )
would have compiled, because only that call has a correct type.
Java generics are invariant.
Suppose we have B extends A
:
B
is a subtype of A
instanceof B
is also an instanceof A
Since Java arrays are covariant:
B[]
is a subtype of A[]
instanceof B[]
is also an instanceof A[]
However, Java generics are invariant:
List<B>
is NOT a subtype of List<A>
instanceof List<B>
is NOT an instanceof List<A>
.Wildcards are used to make it more flexible while preserving type safety.
List<B>
is a List<? extends A>
The difference between your 2 examples is simply that the first one is a list of generic/general animals - you can therefore add any type of animal to it, and any instance of a subclass of type Animal. (e.g. It can contain some dogs, some cats, some porcupines...) Whereas the second - List <? extends Animal>
- will be a list of one specific subtype of class animal. It can be any one you choose (this is set each time at runtime), but only one. It will either be a list of dogs, or a list of cats, or a list of turtles... etc.