What happens inside Java\'s ArrayList (and probably many other classes) is that there is an internal Object[] array = new Object[n];, to w
Whenever an element is read from it, a cast
return (T) array[i];is done. So, a cast on every single read.
Generic is a compile time check. At runtime the type T extends is used instead. In this case T implicitly extends Object so what you have at runtime is effectively.
return (Object) array[i];
or
return array[i];
Wouldn't it be more logical and also slightly faster to just create a
T[] array = (T[]) new Object[n]
Not really. Again at runtime this becomes
Object[] array = (Object[]) new Object[n];
or
Object[] array = new Object[n];
What you are really fishing for is
T[] array = new T[n];
except this doesn't compile, mostly because T isn't known at runtime.
What you can do is
private final Class tClass; // must be passed in the constructor
T[] array = (T[]) Array.newInstance(tClass, n);
only then will the array actually be the type expected. This could make reads faster, but at the cost of writes. The main benefit would be a fail fast check, i.e. you would stop a collection being corrupted rather than wait until you detect it was corrupted to throw an Exception.