-1

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>();
mist
  • 1,853
  • 2
  • 19
  • 33
  • Because of the type cast to the raw `List`. – Luiggi Mendoza Jan 20 '15 at 16:20
  • Because your first example can only lead to pain and suffering, just like the Dark Side. In your second example - you have two actions, both of which are dodgy, but are legal since they have valid uses. – Ordous Jan 20 '15 at 16:20
  • 6
    [First](http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p) and [second](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it). – Sotirios Delimanolis Jan 20 '15 at 16:20

2 Answers2

4

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.

b4hand
  • 9,550
  • 4
  • 44
  • 49
3

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.

David Conrad
  • 15,432
  • 2
  • 42
  • 54
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130