All 15 Generics questions
More in Generics
Advertisement
Java › Generics

How do generics interact with arrays, and why does the JDK itself sometimes use an unsafe cast (like in ArrayList's internal implementation) to work around the inability to create generic arrays directly?

Advanced

Answer

As covered by generic array creation restrictions (new T[] is illegal, stemming from the combination of type erasure and array covariance's already-demonstrated unsoundness), the JDK's own internal implementations (like ArrayList<E>) that need array-backed storage for a generic type work around this by internally using an Object[] array and performing an unchecked, suppressed-warning cast to E[] only at the specific point where a caller-facing typed array needs to be returned (like from toArray(T[] a)) -- this is a deliberate, carefully-reasoned unsafe cast that the JDK's own authors have verified is safe in context (since they control exactly how the array is populated and accessed internally), a pattern application code should approach with real caution since it reintroduces the same type-safety hole generics were designed to eliminate if used incorrectly.
// Simplified illustration of ArrayList's internal pattern for this challenge
public class SimpleGenericList<E> {
    private Object[] elements = new Object[10];  // MUST use Object[] internally, can't do new E[10]

    @SuppressWarnings("unchecked")
    public E get(int index) {
        return (E) elements[index];  // unsafe cast, but JDK-author-verified safe given internal invariants
    }
}
Real-world example A code reviewer flags a custom generic collection class's internal (E[]) cast pattern (mimicking what ArrayList itself does internally) as needing extra scrutiny and thorough test coverage specifically because this exact pattern is a well-known, deliberate exception to normal generics type-safety guarantees, requiring the developer to manually ensure correctness where the compiler no longer can.

Common follow-ups: What specific invariant must be maintained internally to make this unsafe cast pattern actually safe in practice, despite the compiler's unchecked warning?;Why doesn't the JDK just use a List<Object> internally instead of a raw array, avoiding the unsafe cast issue entirely?