Short answer
Generics are invariant precisely to preserve type safety: if List<String> were a List<Object>, you could add an Integer through the Object-typed reference and then read a String back, causing a ClassCastException — the exact problem generics exist to prevent.
Explanation
Arrays, by contrast, are covariant (Object[] can hold a String[]) and therefore unsafe, throwing ArrayStoreException at runtime. When you need flexibility across subtypes you use a bounded wildcard rather than relying on subtyping of the parameterized type.
Common mistakes
- Saying generics are covariant like arrays.
- Not explaining the heap pollution that covariance would allow.