• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Casting Differences - Collections

 
Pritish Chakraborty
Ranch Hand
Posts: 91
C++ Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've just come up with a weird gotcha, I was doing TreeSets.



times is a TreeSet<Integer>. Why does the first line throw an exception? It says something like this -:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from SortedSet to TreeSet<Integer>

at FerryTreeTest.main(FerryTreeTest.java:16)


I think there is a question at the back of Chapter 7 in K&B which deals with the same issue. I'd love some clarification here, though.
 
Henry Wong
author
Marshal
Pie
Posts: 21426
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pritish Chakraborty wrote:I've just come up with a weird gotcha, I was doing TreeSets.



times is a TreeSet<Integer>. Why does the first line throw an exception? It says something like this -:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from SortedSet to TreeSet<Integer>

at FerryTreeTest.main(FerryTreeTest.java:16)


I think there is a question at the back of Chapter 7 in K&B which deals with the same issue. I'd love some clarification here, though.


<rant>
This is a pet peeve of mine -- so feel free to ignore..... I really hate it when people run code that doesn't compile !! I know that IDEs allow you to do it. And I know that you will get an Error when you hit the area of code that had the compile error, but why? Why run something that has a compile error???
</rant>

If possible, try not to mix using generics and not using generics. This mixing was allowed for backward compatibility, and it tends to "weaken" generics (the compiler loses information about the type when you mix like that). And definitely, you should try to never user casting with generics. Casting overrides the type -- and if you are wrong, you will break the generic.... and the compiler will be nice and let you do it.

Anyway, to answer your question.... A TreeSet IS-A SortedSet, but a SortedSet is not necessary IS-A TreeSet. In the second case, you forced it by casting the return instance (the SortedSet), so the compiler allowed it. In the first case, you only casted your original variable, but not the SortedSet that has been returned, so the compiler complained..... and BTW, this casting will just get around the compile issue. I don't think the casting is legal (never mind the last point, just checked the source and it is a TreeSet instance that is returned).

Henry
 
Pritish Chakraborty
Ranch Hand
Posts: 91
C++ Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Calm down brah, I never meant to get you riled up o.o

This is purely for academic interest. I still need to know, for this issue may crop up in some ugly question in OCJP!

So in the second instance, it is casting the result that is returned by the method, while in the first it is casting 'times' illegally.

Got it
 
Henry Wong
author
Marshal
Pie
Posts: 21426
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pritish Chakraborty wrote:Calm down brah, I never meant to get you riled up o.o


Well.... I did say you can ignore the rant.


Pritish Chakraborty wrote:
So in the second instance, it is casting the result that is returned by the method, while in the first it is casting 'times' illegally.


Well, it is hard to tell whether the cast is valid or not -- technically, it is not casting during the runtime execution. It is a compile error, and the generate code just mentions it when you reach that section of code.

As for the compilation issue, I believe in both cases the cast is technically valid (at compile time). It is just that in the first case, you cast a TreeSet<Integer> to a TreeSet, which is okay, but then there is no way to implicitly cast the SortedSet that is returned to a TreeSet. Hence, the compilation error. In the second case, you just explicitly cast the SortedSet to TreeSet, which is valid at compile time.

Henry
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic