Start here. This is the direct spoken answer to practice first.
Overview
The contrast reveals why two similar-looking containers enforce type safety at different times.
Java arrays are covariant, so a String[] can be assigned to an Object[]. The runtime array still knows its component type, so storing an Integer through that Object[] reference throws ArrayStoreException. Generics are invariant, so List<String> cannot be assigned to List<Object>; the unsafe write is rejected at compile time instead. Generic type arguments are mostly erased, so a list cannot perform the same runtime element-type check as an array.