The following code
import java.util.*;
import java.io.*;
@SuppressWarnings("unchecked")
List<Serializable> list = (List<Serializable>) (List<?>)
Collections.singletonList(new Object());
for (Object el : list) { // -> ClassCastException
System.out.println(el);
}
is correct Java (even though the code is suspicious). Using javac and java 6 it throws
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.io.Serializable
while it runs without error when using javac and java 7.
Is it a language change, fixed bug or a hidden feature?
(Note: Code compiled with Eclipse runs without error on all Eclipse versions checked - Helios to Kepler.)
You're polluting the heap by adding your raw
Objectto the collection (which you're having to do the cast dance to make happen). It's not technically illegal, but it is a bug.When you are pulling the value out of your implicit iterator, the Java 6 compiler appears to be casting immediately, while the Java 7 compiler isn't. It's more efficient not to cast to
Serializableif it doesn't need to (since the holding variable is justObject), but this behavior is undefined as far as I understand from the JLS. Try runningjavapon your two.classfiles and looking at the code right around thatforloop (probably right after aninvokeinterfacecall toIterator.next()).