tags:

views:

87

answers:

4

this code compiles fine and when executed produce "004b" how that happen why it do not produce an classcastException.

public static void append(List list) {
    list.add("004b");
}

public static void main(String[] args) {
    List<Integer> intList = new ArrayList<Integer>();
    append(intList);
    System.out.println(intList.get(0));
}
+2  A: 

Because generics are implemented in Java via type-erasure; that is, there is no runtime information about the types, just casts where appropriate. If you were to say

Integer i = intList.get(0);

then it would compile to

Integer i = (Integer) intList.get(0);

and throw a class cast exception.

Since System.out.println() takes an Object as an argument, no casting is necessary.

Stephen
+3  A: 

You're calling the System.out.println(Object) override since the type of intList.get(0) is Integer and there is no Integer-specific overload. After compilation the type information is erased, leaving a return type of simply Object for intList.get(0) after type erasure. That matches the expected type for the println(Object) function call so there is no runtime casting done, and no exception thrown.

John Kugelman
If the type of `intList` was `List<char[]>` an exception would have been thrown.
Tom Hawtin - tackline
+1  A: 

Where are you expecting a ClassCastException to happen?

It won't happen when you call append, because append uses a raw List.

It won't happen when you call println, because println takes an Object, and so no implicit casting is done.

It might be a bit surprising that the overload resolution picks println(Object) rather than println(int) (because that overload does exist). This is because autoboxing has a verly low precedence when resolving overloads (largely for backwards compatibility).

Laurence Gonsalves
umm... why would it choose println(String)? "intList.get(0)" has type Integer, and so naturally it chooses println(Object)
newacct
Yeah, I somehow got confused there. Should be fixed now.
Laurence Gonsalves
+4  A: 

Suggestions:

  1. Don't mix raw and generic typing
  2. Turn on your Java compiler's generic type warnings. That will tell you about your unsound code.
  3. If you use a "checked collection" type (e.g. as created using Collections.checkedList(...)) you will get an exception when you insert an incorrectly typed object into the collection.
Stephen C