As Integer IS-A Object and our list can accept Object(super class of number)so this value is stored in List as Object.
No! This the trap I nearly fell into with my post earlier... it is in fact quite confusing at first glance. Let me
try to explain, although this may not sound crystal clear! If not, please let me know how to clarify.
What you need to grasp is the difference between a
generic collection (or any other object) and a
generic reference.
List<Number> means an object (in fact a List collection) which can hold Numbers or any subclasses. That's the easy bit!
List<? super Number> is a
reference data type, meaning that the actual value held by such a variable should be a List<X> where X is a Number or a superclass of Number. List<? super Number> does
not mean the list can contain any superclasses of Number. In fact, in general, this is not true, as we now show...
Let's take two examples:
this is clearly valid because Object is a superclass of Number; so I go and invoke:
and everything would in theory work okay (this won't happen, the compiler will complain and the next example shows why). But now I alter the declaration to:
Again this is valid because Number is treated as a superclass of itself. But now I go to add an Object:
Now what happens? The actual list type is ArrayList<Number>, so we can't add an Object to it! This will raise a compiler error.
So both examples raise a compiler error because you can't add a superclass of a class X to any (lower bound) generic type of the form "? super X" simply because the compiler doesn't know what type of list is actually on the left. The only guarantee we can make about List<? super Number> at
compile time therefore (and due to type erasure this is the only place generics are really useful) is that the List will contain subclasses of Number - this is because a List<X> with X a superclass of Number implies that it may contain any elements which are Numbers or subclasses of it (think about an inheritence tree and this becomes 'obvious').
A key rule is: you can only create definite generic types - you cannot use wildcards when creating a new object (this makes little sense). You can only use wildcards to reference definite generic types.
You are correct about the autoboxing, but that gets converted to Integer directly, which is a
subclass of Number and therefore can be added to the List<? super Number> type.
You are correct that "we try to treat an object as number which causes the error". But the explicit reason for the compilation error is because we have no
upper bound on the generics type, it could potentially refer to a List<Object> (since Object is a superclass of Number). So the only guaranteed return type from the get method or from an Iterator is Object - the only common data type for all objects in the JVM.
[ May 09, 2006: Message edited by: Charles Lyons ]