The full picture
// Arrays: compiles, blows up at RUNTIME
Object[] objs = new Integer[2]; // covariance allows this
objs[0] = "boom"; // ArrayStoreException
// Generics: caught at COMPILE time
List<Integer> ints = new ArrayList<>();
// List<Object> objs2 = ints; // does not compile — invariance
// Heap pollution via raw type:
List raw = ints; // raw type sidesteps checking
raw.add("boom"); // warning only…
Integer i = ints.get(0); // ClassCastException HERE, later, elsewhere- Arrays carry their component type at runtime and check every store — that's the safety net generics deliberately moved to compile time.
- Generic varargs create arrays of erased type — hence the
@SafeVarargsannotation on methods that promise not to store into or leak that array. - This is why 'prefer lists to arrays' (Effective Java Item 28) for API design — arrays + generics mix badly (
new List<String>[10]is illegal).