KS & BB
SCJP 1.5 book explains generics very beautifully. Referring to the same the following assignments are valid:
LinkedList <? super Integer> l1 = new LinkedList <Integer>();
//l1 can accept a generic type which is an Integer or
//superclass of Integer. Moreover i can add an object to list l1
LinkedList<? extends Number> l2 = new LinkedList <Integer>();
//l2 can accept a generic type which is an Number or
//subclass of Number. Moreover i can NOT add an object to list l2
LinkedList <Number> l3 = new LinkedList <Number>();
//l3 can accept a generic type only of type Number. i can add to
//this list
The following are invalid assignments:
LinkedList <? extends Number> l4 = new LinkedList<? extends Number>();
//I cannot use wildcard notation while creating an object as it is
//allowed to be used only for reference declarations
Quoting KS && BB "Keep in mind that the wildcards can be used only for reference declarations(including arguments, variables, return types, and so on). They can't be used as the type parameter when you create a new typed collection. Think about that�while a reference can be abstract and polymorphic, the actual object created must be of a specific type. You have to lock down the type when you make the object using new."
Moreover, generic types are verified by the compiler by a process called "type erasure" hence the generic type information is removed after verification at compile time.
so based on the facts above I guess the compiler does the following:
Queue<? extends Number> q1 = null;
Queue<? super Integer> q2 = null;
q1 = q2; //What should happen here?
//--> The compiler resolves the generic type of reference variable
//--> q2 to be containing wild card characters hence throws a
//-->compile time exception.
q2 = q1 //What should happen here?
//--> Same as above
So if you say
Queue<? extends Number> q1 = null;
Queue<Integer> q2 = null;
q1 = q2; //This will compile as the compiler is able to lock the type on
//the right hand side of the assignment operator.
q2 = q1; //Will not compile as the compiler is NOT able to lock the type
Hence the compiler makes sure that when an object or object reference is assigned to a generic typed reference variable the reference variable on the right hand side should have a generic type not containing wild card notation.
i hope this helps. Any ranch hands please correct me if i am wrong.