T.J. Crowder
2010-10-07 11:12:59
the String part is lost at runtime (erasure), so no conversion actually takes place. But it is very wrong to do it the way he did.
Bozho
2010-10-07 11:14:58
@Bozho: Clearly not in the `Iterator<E>` implementation. When I compile his code with the Sun Java 6 compiler (1.6.0_20) on Linux and run it, I reliably get the `ClassCastException`.
T.J. Crowder
2010-10-07 11:16:37
I ran it and it does not throw an exception :), 1.6.0_20, Windows XP
Bozho
2010-10-07 11:18:22
Well it doesn't throw a ClassCastException because I'm using Object to iterate over the list.
robert
2010-10-07 11:18:34
@robert: But you're doing that with a `Iterator<String>`.
T.J. Crowder
2010-10-07 11:21:43
@Bozho: Don't know what to tell you. Sun's Java 6 compiler and runtime, on Linux, throw the exception.
T.J. Crowder
2010-10-07 11:21:59
It isn't throwing an Exception on Linux 1.6.0_20 neither. It only throws one when you try to alter the type in the for control from Object to String for example.
Octavian Damiean
2010-10-07 11:23:28
@Octavian: *"It isn't throwing an Exception on Linux 1.6.0_20 neither."* Yes, it is, for me. If it isn't for you, I wonder what's different?
T.J. Crowder
2010-10-07 11:27:18
@Bozho: Hmm...Compiling on 1.6.0_21 (for me) inserts a `checkcast <java/lang/String>` instruction, which causes the exception.
Tim Stone
2010-10-07 11:27:40
@Octavian What compiler are you using?
robert
2010-10-07 11:28:16
@ T.J. Crowder: I have no clue what the difference is. I can run it without any exceptions for as many times as I try.
Octavian Damiean
2010-10-07 11:29:28
@robert: 1.6.0_20
Octavian Damiean
2010-10-07 11:31:35
This is a rather interesting discussion, but I think we all agree what is wrong with the code and what has to be fixed :)
Bozho
2010-10-07 11:32:07
@Octavian: Yes, but is it Sun's compiler? Or the OpenJDK?
T.J. Crowder
2010-10-07 11:32:44
@robert: Sorry Sun's yes.
Octavian Damiean
2010-10-07 11:33:47
@Bozho: *"...but I think we all agree what is wrong with the code and what has to be fixed"* Completely. :-)
T.J. Crowder
2010-10-07 11:35:08
+1
A:
I can't reproduce it either, but I spot the following mistakes that must be corrected:
- make
getObjects()
returnList<Integer>
, rather than a raw type - Don't expect
List<String>
, but aList<Integer>
instead - When iterating, loop
for (Integer o : list)
Bozho
2010-10-07 11:14:14
A:
The problem is the method static List getObjects() {
returns a generic (non parameterised) List
. And you assign it to List<String>
. This line should give a compiler warning, and that should have signalled a problem.
Nivas
2010-10-07 11:15:46
A:
This part :
List<String> list = getObjects();
for (Object o : list) { // ClassCastException?
System.out.println(o);
}
Will be simplified as
List<String> list = getObjects();
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
Object o = iterator.next();
System.out.println(o);
}
But the implementation of Iterator will try to cast when calling the next()
method the content send by the Iterator
in a String
.
That's why you have a CCE.
Solutions :
Either use generics everywhere or don't use them, but it's really important to be consistant. If you had returned a List<Integer>
or a List<? super Integer>
you would have seen this problem at compilation time.
Colin Hebert
2010-10-07 11:20:34