The Array Problem
We left off with a constructor that will not compile:
arr = new T[10]; // does not compile!
The reason comes from how Java implements generics. Java compiles a generic class to a single .class file, shared by every element type you use it with. It does not generate a separate compiled class for DynamicArray<Student> and DynamicArray<String>. To do that, it erases the type parameter: by the time your program runs, the running code no longer knows what T stands for. Neither one records Student or String at runtime.
An array is different. An array in Java does remember its element type while the program runs, and it uses that type. Every time you store a value into an array, the JVM checks that the value is an instance of the array’s element type, and it throws an ArrayStoreException if it is not. That check needs a real type to check against, so the array has to be created with a concrete element type.
Put those two facts together. Creating the array requires a concrete element type at runtime, and erasure means T is not available at runtime. So Java does not allow new T[10].
The workaround
We cannot make an array of T, but we can make an array of Object, and then tell the compiler to treat it as a T[]:
@SuppressWarnings("unchecked")
public DynamicArray() {
arr = (T[]) new Object[10];
size = 0;
}
The cast (T[]) is us saying to the compiler: “trust me, I will only ever put Ts in here.” The compiler cannot verify that promise, so it would normally warn us with an unchecked cast warning. The @SuppressWarnings("unchecked") annotation tells the compiler not to issue that warning.
Why is the promise safe to make? Because arr is private. The only way anything gets into it is through our own methods, add and set, which only accept T. And the only way anything comes out is through get, which returns T. From the outside, the array behaves exactly like a real T[]. Nothing outside the class ever sees the Object[] underneath.
What ArrayList does
This is the standard idiom, and the Java library itself uses it. Java’s own ArrayList, which is the library’s version of our DynamicArray, stores its elements in an Object[] and casts them on the way out. It does that for the same reason we did.
With the constructor working, our generic DynamicArray compiles.