Guillaume Jeudy wrote:
I have yet to find a clear explanation explaining the semantic difference between the 2 notations.
Example:
A List<? super Number> means a list of an unknown type that is a super of Number (or Number). This means that it can be a list of Number instances, or it can be a list of Object instances. It does *not* mean a list that can hold either Number or Object instance -- the list is of a particular type, it is just that the compiler doesn't know what it is.
A List<? extends Number> means a list of an unknown type that is a subclass of Number (or Number). This means that it can be a list of Number instances, it can be a list of Integer instances, it can be a list of Double instances, etc. etc. etc. It does *not* mean a list that can hold either Number, Integer, or Double instances -- the list is of a particular type, it is just that the compiler doesn't know what it is.
Guillaume Jeudy wrote:Why can you add() only with ? super *type* and get() only with ? extends *type* ?
Think about it a bit... In the first case, it can be a list a Object instances or it can be a list of Number instances. In order to do any operation, it must work for both -- meaning that you can only add something that is both IS-A Object and IS-A Number. This means that you are allowed to add Number instances, Integer instances, Double instances, etc. -- as anything that subclass Number IS-A Number, and IS-A Object.
In the second case, it can be a list a Object instances, it can be a list of Integer instances, or it can be a list of Double instances. In order to do any operation, it must work for all the cases -- meaning that you can only add something that IS-A Object, IS-A Integer, IS-A Double, etc. etc. This means that you are allowed to only add null, as that is the only thing that IS-A all possible subclasses of Number.
As for get(), that statement is completly not true. But I would let you work out why the types returns is what it is. It makes sense, you just have to think it through a bit.
Henry