Generic Subtypes


Edit the material here!

We know that Integer is a subtype of Number. Consider the following lines of codes

  // Integer is a subtype of Object
Number n = 1; // polymorphism here. okay.
System.out.println(n); // 1

// But ArrayList<Integer> is not a subtype of ArrayList<Number>
ArrayList<Integer> lst = new ArrayList<Number>();
// compilation error : incompatible types: ArrayList<Number> cannot be converted to ArrayList<Integer>

When we try to upcast ArrayList to ArrayList, it triggers a compilation error "incompatible types". This is because ArrayList is NOT a subtype of ArrayList, eventhough Integer is a subtype of Number.

This error may seem strange. Why?

  List<Integer> intLst = new ArrayList<>();
List<Number> numLst = intLst; // incompatible types: ArrayList<Number> cannot be converted to ArrayList<Integer>.

Why do we get a compilation error in line 2? Suppose it succeeds, and some other number (e.g. Double or Float) are added into intLst, then intLst will get "corrupted" since it no longer only contains Integers, as references of numLst and intLst share the same value.

On the other hand, the following is valid.

  // ArrayList is a subtype of List
List<Number> lst = new ArrayList<>();

That is, ArrayList is a subtype of List, since ArrayList is a subtype of List and both have the same parametric type Number