Thursday, May 26, 2011

Why in Java ?


I have some doubts regarding Typesafe(Generics) Collection, Arrays with respect to covariance. I post that as a writeup.

What is a covariant ?
Using (Assigning or returning) subclass object where super class object is expected.

In Java
1. Collection (with generics) is not covariant.
2. But Arrays in Java supports this covariant.

ArrayList<Number> objList = new ArrayList<Integer>(); // illegal
Number[] nrArr = new Integer[10]; // legal

Does it mean Generics is designed well and Array is not ?

Here is the sample code for reference.

// Generic Collections

ArrayList<Number> numberList = new ArrayList<Integer>(); // illegal;

or

ArrayList<Integer> integerList = new ArrayList<Integer>();
ArrayList<Number> numberList = integerList; // illegal;

Above assignment will give you compile time error as Type mismatch: cannot convert from ArrayList<Number> to ArrayList<Integer>. This is not allowed for a vaild reason that if it is allowed in future program may add an instance which might break the type-safety of integerList;

numberList.add(new Float(0.0)); // This fades the typesafety of strList

Consequence is same for Arrays. i.e We can assign wrong types to superType reference array which will lead to run time errors. But why is this allowed ?

// Arrays

Number[] nrArr = new Integer[10];
nrArr[0] = new Float(0.0); // Compiles well but at runtime it will fail.

or

Integer[] intArr = new Integer[10];
Number[] nrArr = intArr;
nrArr[0] = new Float(0.0); // Compiles well but at runtime it will fail.


I don't understand why is this allowed in Java. Is this a miss or my misunderstanding ?