Very broad questions that cover an entire subject area are difficult if not impossible to answer here. My main suggestion to you is to obtain other resources to study such as online tutorials and perhaps other books. While hopefully someone may provide a better answer for your current questions, I predict that you'll have better success if your questions are much more specific.
Good luck. [ June 22, 2008: Message edited by: pete stein ]
Taken directly from my own notes that I used to prepare for SCJP 5.0:
1. The type of the variable declaration must match the type you pass to the actual object type. List<Foo> f = new ArrayList<Foo>(); //OK List<Foo> j = new ArrayList<Bar>(); //NOT OK even if Bar is-a Foo Parent myArray = new Child; //OK when Child is-a Parent
2. Method myMethod(List<Animal> list) can not accept a List<Dog>, List<Cat> ONLY List<Animal>. List<Animal> list = new ArrayList<Animal>(); list.add(new Dog()); //OK when Dog is-a Animal list.add(new Cat()); //OK when cat is-a Animal
3. Method myMethod(List<? extends Animal> list) CAN accept a List<Dog> ONLY if you do NOT ADD to the list List<Dog> listDog = new ArrayList<Dog>(); myMethod(listDog); //OK only if myMethod doesn't add to the list.
4. <? extends ...> works for both classes and interfaces, you use extends for both.
5. <? super Dog> - Accept anything of type Dog or the SUPERTYPE of Dog, then you can add to this list.
6. <?> means you can pass ANY type (Dog, Cat, Car, Bag) but you CAN NOT add to the collection <Object> means you can ONLY pass an Object type, but you CAN add to this collection 7. <?> = <? extends Object>, in both cases you can't add to the collection anyway
8. List<?> foo = new ArrayList<? extends Animal>(); // NO GOOD!!! WILL NOT COMPILE, can't use wildcard on right hand side