Array covariant, List invariant
Arrays are covariant
Covariant simply means if X is subtype of Y then X[] will also be sub type of Y[]. So we can write the following affectation
Dog[] dogs = new Dog[10];
Animal[] animals = dogs; // compiles
animals[0] = new Cat(); // throws ArrayStoreException at runtimeArrays are reifiable and covariant, means their type information is fully available at runtime. Therefore arrays provide runtime type safety but not compile-time type safety.
List are invariant
If this was allowed with generic collections. What happens when you try to add a Cat to this List<Animal> which is really a List<Dog>.
List<Dog> dogs = new ArrayList<Dog>();
List<Animal> animals = dogs; // not compile, but let's say it works
animals.add(new Cat());
Dog dog = dogs.get(0);Why?
As a reminder, generics are erased and invariant. Due to erase type, List doesn’t know the type of it’s element at the runtime. To avoid error, Java provide compile-time type safety.
List<Dog> dogs = new ArrayList<>();
List<Animal> animals = dogs; // compile-time error
animals.add(new Cat());Conclusion
Java
arraywill raise an error at the runtime : reifiable and covariantWhereas
Listwill raise an error at the compile-time : erased and invariant