I was running some tests earlier and could not find an explanation as to why this code does what it does:
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList(Arrays.asList(Double.valueOf(0.1234)));
System.out.println(list.get(0)); //prints 0.1234
Object d = list.get(0);
System.out.println(d.getClass()); // prints class java.lang.Double
System.out.println(list.get(0).getClass()); // ClassCastException
}
}
That raises a few questions:
EDIT
I understand the following 2 statements:
List aList = new ArrayList(); //I can add any objects in there
List<Integer> aList = new ArrayList<Integer>(); //I can only add something that extends Integer in there
But I don't understand why this one is authorised and why it actually works to some extent at runtime although some operations produce a ClassCastException - I would have expected a ClassCastException at the first line of the code posted above:
List<Integer> aList = new ArrayList(); //I can any objects in there
This:
new ArrayList(Arrays.asList(Double.valueOf(0.1234)))
creates a raw (untyped) ArrayList, in to which you can place anything. This is the correct way to do it:
new ArrayList<Integer>(Arrays.asList(Double.valueOf(0.1234)))
which should now not compile.
If you write
... new ArrayList<Integer>(...
instead it will cause a compiler exception.
On why it works:
System.out.println(list.get(0)); //prints 0.1234
The method Object.toString() is the same in Double and Integer (And because System.out.println() expects an Object this is not cast into an Integer (the compiler optimized the cast away))
Object d = list.get(0);
System.out.println(d.getClass()); // prints class java.lang.Double
Same goes for .getClass(). Here the optimizer again dropped the cast.
System.out.println(list.get(0).getClass()); // ClassCastException
This actually creates an Integer from the list and that fails. It does the cast because the optimizer thought it need to do it, because its not obvious that it doesn't need to.
If you would change that last line to:
System.out.println(((Object)list.get(0)).getClass());
it works :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With