Java uses type erasure
It is my understanding that new ArrayList<String>()
is converted into its raw type, and that a lot of syntactic sugar is used to pretend that this ArrayList of Object acts like an ArrayList of String. Java refers to this as type erasure.
For example
This is what I wrote in Java:
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList<>();
stringList.add("foo");
String s = stringList.get(0);
}
When I decompiled the byte code, I got this:
public static void main(String[] args) {
ArrayList<String> stringList = new ArrayList();
stringList.add("foo");
String s = (String)stringList.get(0);
}
Therefore
Why couldn't new T[]
be converted to (T[]) new Object[]
automatically, using the same "shtick" the compiler pulls for type erasure?
Please don't refer me to this question: What's the reason I can't create generic array types in Java? In particular this comment:
The problem is deeper than pointed in that answer, so further investigation is needed. As you said type info is erased and in compiled code we have no difference between two generic types - all we have is base type - so why for
T[]
- compile toObject[]
. In this case everything will be fine - array will remember that it was created with object type and will let save all types. However as for me the real problem is that arrays are covariant meaning thatAnimal[]
can be assigned toObject[]
. On the other hand generics are notArrayList<Animal>
can not be assigned toArrayList<Object>
Because this logic is flawed!
There are two processes going on here.
The compiler enforces an "artificial" invariance to
ArrayList<String>
.The compiler casts the
Object
intoT
.
Again, why couldn't arrays of generics be implemented in Java using the simple syntactic sugar that form all generics, while maintaining the normal covariance of arrays?