Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Polymorphic collection behavior

 
Gerard Charles
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's my understanding that, class A and class B extends A, a Collection<A> can not be (directly) assigned to from Collection<B>?
Given:


fails. However, I can get it to work if I put the cast inside a generic function:


updated test function works fine:

Is there a way to perform the cast without using a separate function? (And any explanation of why it works inside function but not directly would be cool, too.)
 
Ireneusz Kordal
Ranch Hand
Posts: 423
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Gerard Charles wrote:
Is there a way to perform the cast without using a separate function?

Just cast to untyped collection:

 
Gerard Charles
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, of course. "Collection" is okay but "Collection<A>" isn't. (I hate Java "generics").

Thanks!
 
Martin Vajsar
Sheriff
Pie
Posts: 3751
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is explained the reason why Collection<B> cannot be assigned to Collection<A>: http://download.oracle.com/javase/tutorial/extra/generics/subtype.html. Another article has more on differences between arrays of related types and collections: http://www.ibm.com/developerworks/java/library/j-jtp01255.html

Maybe you could use generic wildcards to resolve your problem without the need for type-unsafe cast?
 
Gerard Charles
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, using, Collection<? extends A> seems to work.
 
Matthew Brown
Bartender
Posts: 4565
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically, casting from Collection<B> to Collection<A> isn't safe. If it was allowed, it would give you a way of addings things other than B to a Collection<B>. Which defeats the whole object of generics.

Your generic method is effectively tricking the compiler. The compiler doesn't know what T and U are going to be. They could even be the same. So it will allow it, but it will generate warnings that you've had to suppress.

Then, because generic information doesn't exist at run time, the cast has no effect when it's running.

The bottom line is...if you're having to do this, there's almost certainly a better way! (Using wildcards might be it, depending on what you're actually trying to do).
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic