12

Why is it that when I try to make an array of ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40]; there is an error and java does not allow this?

Is there a reason related to java's implementation of generics, generics in any language, or something arbitrary?

1

3 Answers 3

21

This is one of major holes in Java's generics, arrays are covariant, meaning that an array of type Foo[] is a subclass of Object[] and ParentOfFoo[]. Contrast this with List<Foo> which doesn't have this behavior.

This was important when Java didn't have generics (until Java 5) because otherwise, something like a generic sorting function was just impossible.

However it has this tricky problem that arrays like to know what type they are at runtime. However generics in Java is based on type erasure. These two things don't mesh well at all and that's where we get our problem.

So the long and short of it is, in Java 1, covariant arrays partially filled the hole that a lack of generics created. However when they tried to properly fill this hole, backwards compatibility meant that arrays were pretty impossible to implement.

In fact, the guy who actually created the framework for generics, Martin Odersky, talked about this here during an interview about why he made Scala. (Pretty fascinating if you are interested in Scala's history at all)

3

Is there a reason related to java's implementation of generics, generics in any language, or something arbitrary?

Actually, it's somewhat arbitrary.

The problem is that it allows a hole in the type system, since ArrayList<T>[] can be casted to Object[] and then you can put an ArrayList<U> in the array, where U != T.

Java designers decided to block this hole as eagerly as possible, by not allowing new ArrayList<T>[N] at all.

However, it could also have been plugged by not allowing upcasting of arrays of generics (without an "unchecked" warning).

2
  • This answer is underrated. Very simple and doesn't use jargon on vague terms. Thanks very much. Jun 20, 2018 at 16:58
  • 2
    You might want to elaborate on why this is different to the case where you put an Integer into an Object[] that's actually a String[]
    – Caleth
    Nov 20, 2019 at 17:06
-3

because the array is covariant which every type is a subclass of the object so this gives an error in run time due to casting exception. while the generic is invariant so when it builds on the type ensure or type-safe so if the type not like it creates type it gives a compiler error.

Not the answer you're looking for? Browse other questions tagged or ask your own question.