Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Generics polymorphism and Iteration

 
Tanu Gulati
Ranch Hand
Posts: 113
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i have the following code where i wanted to iterate through "type "


In for loop either i gave "Number" or "Integer" i am getting error. i can iterate using Iterator also but i am unable to under stand why it is not working in current situation.



[ November 22, 2008: Message edited by: Tanu Gulati ]
 
Campbell Ritchie
Sheriff
Posts: 51453
87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please give us full details. What error are you getting? Is it at compile time or runtime? Which line number does it blame?
 
Rob Spoor
Sheriff
Pie
Posts: 20753
68
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem occurs at line 2, right?

With "? super Integer", it could in reality be List<Integer>, List<Number>, List<Object> or even an interface implemented by Integer like List<Serializable> or List<Comparable>.

Now consider it is in fact a List<Serializable>. The assignment will match, and you can add Integers without a problem (because Integer IS-A Serializable). But it can also contain other objects like File. Now you try to retrieve everything as Integer, but that could result in a ClassCastException. Hence the compiler won't even allow it.

The rule:
- "? super X" allows you to add anything that IS-A X, but you can only retrieve as Object (without casts)
- "? extends X" allows you to retrieve as X (without casts) but you cannot anything - because the actual type might not be X itself.
- "X" allows you to both add anything that IS-A X and retrieve as X (without casts)
 
Tanu Gulati
Ranch Hand
Posts: 113
Hibernate Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hey thanks Rob nice explanation.
 
Brian Legg
Ranch Hand
Posts: 488
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good info Rob, I like the concise rules.
 
Brian Legg
Ranch Hand
Posts: 488
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob... you said, "- "? super X" allows you to add anything that IS-A X, but you can only retrieve as Object (without casts)"


Shouldn't that say that "? super X" allows you to add anything that X IS-A, not IS-A X? I mean replace X with Dog and if you add Animal that that's ok because Animal is a super class of Dog, but "Animal IS-A Dog" is not necessarily true.

Any help appreciated.
 
Rob Spoor
Sheriff
Pie
Posts: 20753
68
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Brian Legg:
Rob... you said, "- "? super X" allows you to add anything that IS-A X, but you can only retrieve as Object (without casts)"


Shouldn't that say that "? super X" allows you to add anything that X IS-A, not IS-A X? I mean replace X with Dog and if you add Animal that that's ok because Animal is a super class of Dog, but "Animal IS-A Dog" is not necessarily true.

Any help appreciated.

If X is Dog, surely you can't add an Animal. The actual type can still be Dog - the super (and extends) are a bit misleading. And adding Animals to a List of Dogs is dangerous. What if the Animal is a Cat?! DISASTER!

Like I said, any object that IS-A Dog (a.k.a. any object for which "instanceof Dog" returns true) can be added. I'm just using the terms IS-A and HAS-A because a lot of people are acquainted with those.
 
Brian Legg
Ranch Hand
Posts: 488
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sure, I know what you meant by IS-A and HAS-A, I just thought your sentence was wrong, lol. I'm sure it's not but it seems I am getting conflicting (in my head anyways) info from K&B book.

Here is a quote from K&B6, "public void addAnimal(List<? super Dog> animals) is essentially saying, "Hey compiler, please accept any List with a generic type that is of type Dog, or a supertype of Dog. Nothing lower in the inheritance tree can come in, but anything higher than Dog is OK.""

By that explanation why is it dangerous to give it an Animal if an Animal is a supertype of Dog, aren't all supertypes of Dog safe? Any help appreciated.

Thanks!
[ November 24, 2008: Message edited by: Brian Legg ]
 
Rob Spoor
Sheriff
Pie
Posts: 20753
68
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We've gotten mixed up I think.

You can assign a List<Animal>, but you can't add an Animal. That's because you don't know if the List can accept Animals or not - List<Dog> certainly can't, and it matches List<? super Dog>.

But you do know that List<Animal> can accept Dogs, and even Chihuahuas. So that's why adding anything that IS-A Dog is safe.
 
Brian Legg
Ranch Hand
Posts: 488
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I see, I've gotten mixed up when it comes to assigning one generic collection to another collection vs. adding a generic type to a generic collection.

Dang!!

If I ever fully understand all this generic stuff I will be amazed!!

Thanks for the help... again!!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic