The "Get and Put Principle" in section (2.4) is a real gem from Java Generics and Collections:
The Get and Put Principle: use an
extends wildcard when you only get
values out of a structure, use super
wildcard when you only put values into
a structure, and don't use a wildcard
when you both get and put.
Also, declaring a type as List super Shape> shapeSuper
is kind of bad form as it constrains its use. Generally, the only time I use wild cards is in method signatures:
public void foo(List super Shape> shapeSuper)