Why is this not allowed?(compile time error)
List<Object> o1 = new ArrayList<String>();
Why is this then allowed? (only warnings)
List<Object> o2 = (List)new ArrayList<String>();
Why is this not allowed?(compile time error)
List<Object> o1 = new ArrayList<String>();
Why is this then allowed? (only warnings)
List<Object> o2 = (List)new ArrayList<String>();
List<Object>
is not a super type of ArrayList<String>
. Converting to that type is unsafe as it would allow you to add an arbitrary Object
to the ArrayList<String>
which could then cause a runtime error where code that was expecting a String
received a different type of object.
List<String> a = new ArrayList<>();
// this next line is not allowed but let's assume it was
// List<Object> o1 = a;
Integer i = 5;
o1.add(i);
// this next line would cause a runtime error, but appears safe
String s = a.get(0);
Casting to the raw type first bypasses all the safety checks that the compiler normally performs, and thus it is allowed, but is still unsafe for the same reason. However, all usage of raw types give a warning exactly because they can cause this type of unsafe behavior.
Java doesn't have reified types and unless the compiler can check this is ok, there is no runtime check.
This is allowed for backward compatibility. i.e. for code written without generics.
It produces a warning and even if casting from a generic to a non generic collection as not allowed you would always need to be able to do things like this.
Object o = new ArrayList<String>();
List<Object> list = (List<Object>) o;
For example when you serialise an object you write just an object and when you deserialize it, readObject()
just returns an Object. You how to allow it to be cast to a specific type.