A few of my thoughts on Generics and the "? extends" syntax...

In the simplest case, one may wish to create a collection of objects sharing a hierarchy (say a Vector of Dogs and Cats). The obvious way to do this is ...
Vector<Animal> dogs = new Vector<Animal>();
dogs.add(new Dog());
dogs.add(new Cat());

You cannot use the following construct ...
Vector<Animal> animal = new Vector<Dog>(); // u get a compile error because you are trying to assign one collection type to another. Dog may be derived from Animal, but a collection of Dogs is not derived from a collection of Animals.

Similarly
Vector<? extends Animal> dogs = new Vector<Dog>(); // Will compile
dogs.add(new Cat()); // This will not compile (for the same reason)

Let's explain this by illustrating a more complicated requirement...
1) In one scope, you want to create a Vector comprising the same animal type (say Tiger) and do not want any other animals to reside in this Vector. (Assume a zoo with various sections, each section with one animal... u do not want tigers and kangaroos to reside in the same area)

2) At another scope, you want to treat these 2 vectors as belonging to one type of collection. For example you would want to get the name and ID of the Animal (the same parent method in both classes). (All animals in the zoo are identified by a name and serial ID)

This is where the "? extends" syntax comes in...


We define a vector of tigers (to make sure a kangaroo does not get in this collection)...
Vector<Tiger> tigers = new Vector<Tiger>();
tigers.add(new Tiger("Sher Khan", 1345));
tigers.add(new Tiger("Stripes", 4356));

Similarly a collection of kangaroos...
Vector<Kangaroo> kangaroos = new Vector<Kangaroo>();
kangaroos.add(new Kangaroo("Jumping Jack", 6743));
kangaroos.add(new Kangaroo("Monterey Jack", 6535));

When we want to treat each species as an Animal, we define the collection as follows....
Vector<? extends Animal> animals;

And the signature of the method returning (a Tiger or a Kangaroo as an Animal), below in TigerSection we have this method...
public Vector<? extends Animal>returnAnimalList(){ return this.tigers; }

and in class Zoo, you read the list of Tigers and access them as Animals (to get name and ID)...
this.animals = returnAnimalList();

You can obviously use a similar construct as a parameter (instead of the return value as show in the example above).

I hope this clarifies the use of the '? extends' syntax