Pierluigi Di Giacomo wrote:Hello, I read several times the chapter of K&B for OCPJP6 about collections and generics (Chapter 7) and I think I have understood everything in it. However, I think the authors missed a tiny part when they tell about the keyword "super" used along with the wildcard "?" inside the generic declaration syntax (angle brackets <...>). All they say is that, with that keyword in place in a method parameter, it is then legal to call the method with an argument made by a class that is instanceof the collection used by the parameter, and a superclass of the class used by the parameter. This way, it is still possible to add SOMETHING to the collection passed to the method, even if the parameter shows the wildcard "?".
The authors teach you what kind of collection (and with what generic type) it is legal to pass to the method, but they do not elaborate further about WHAT type of objects can be added to such a collection.
Given this,
if I try to insert a Fruit object (line 10) the code won't compile. Why ? Most importantly, what type of objects is it legal to add inside the addFruit method ?
Did I miss some part of the chapter where this is well taught or did the authors miss this ?
Henry Wong wrote:
A "List<? super Apple>" is a list that may be a "List<Object>", a "List<Fruit>", or a "List<Apple>". And here is the important part; the compiler doesn't know which type (of the three types) of list it is. So, since the compiler doesn't know which one it is, it can only allow operations that can work regardless of which list type it is.
This means that you can only add objects which IS-A Object, which IS-A Fruit, *AND* which IS-A Apple. And while a Fruit IS-A Object, and IS-A Fruit, there is no way to confirm (at compile time) that it IS-A Apple, which means trying to add a Fruit will cause a compile error.
Henry
Helen Ma wrote:Yes, Golden and Fuji IS-A Apple and fruitList can add them.
List<? super Apple> won't allow you to add any object above Apple type. This rule applies to other types too.
Can you add Object o = new Object() to fruitList? No. During runtime, the compiler can only tell fruitList is a list containing Apple or super type of Apple. The compiler will say "What if Object o is new Animal()?"
The compiler won't let you add any type other than Apple because it prevents you in advance that you will add some type that is not in this hierarchy chain : Apple ->Fruit->Object. For example, Animal is not in this hierarchy chain. The compiler prevent you from adding it before runtime.
How about Fruit f = new Apple()? No, you can't add it to fruitList. The compiler will say "I only know f is a Fruit during compile time. I will know it is an Apple during run time. What if Fruit is a Pear? " Pear is not in the hierarchy chain : Apple ->Fruit->Object.
Can you add Object o = new Fuji () to this fruitList? No. At compile time, o is an object type, not Fuji type.
Remember one thing: it is ok to define List<? super Apple> fruitList = new ArrayList<Object>(). But it is NOT ok to add Object o to fruitList.
I wasn't selected to go to mars. This tiny ad got in ahead of me:
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
|