I am running this small piece of code:
List<String> abc = new ArrayList<String>();
abc.add("something");
List raw = abc;
List<Integer> def = raw;
System.out.println(def.get(0));
I don't understand why it is not throwing an exception when the list containing a String
member is being assigned to an Integer
List. Moreover, how is an Integer
list storing and printing a String
? Can someone help me out here?
This is the reason why you shouldn't use raw types.
When you do
List raw = abc;
You, yourself erasing the type with list. So They are free of types and no error from compiler. To gain the benefits of generics you should avoid using raw types.
And also consider reading about Type Erasing. At run time the lists do not have any idea about their types. Types get erased and they just get whatever available in the list.
The error you expected is a compiler error and at the same time you avoided giving a type first. Hence there is no error.
If you really want to see an exception, try to assign an element from the current list to an Integer. Though compiler won't give you any error, at runtime the types get match and you run into exception.
If you have a look at Raw Types docs, you see almost same example
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8); // warning: unchecked invocation to set(T)
The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.