I'm studying generics in this period and today I've found this mystery for me.
Let's consider the following dummy class:
public class Main{
public static void main(String[] args) {
Container<Integer> c = new Container<Integer>();
c.getArray(); //No Exception
//c.getArray().getClass(); //Exception
//int a = c.getArray().length; //Exception
}
}
class Container<T> {
T[] array;
@SuppressWarnings("unchecked")
Container() {
array = (T[])new Object[1];
}
void put(T item) {
array[0] = item;
}
T get() { return array[0]; }
T[] getArray() { return array; }
}
Because of erasure, at runtime, the T[] return type of the getArray() method is turned into a Object[], which is completely reasonable to me.
If we access that method as it is (c.getArray()) no Exceptions are thrown, but if we try to call some methods on the returned array, for example c.Array().getClass(), or if we try to access to a field, for example c.getArray().length, then the following exception is thrown:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
Why is this Exception thrown? Why is it not thrown also for the simple c.getArray() call? Why is it trying to cast to Integer[] if we are simply calling getClass() or accessing length? Are getClass() and length not available also for Object[]?
Thanks in advance for your many (I hope) and explanatory (I hope this too) answers.