The full picture
List<String> names = new ArrayList<>();
names.add("a");
String s = names.get(0);
// After erasure (conceptually):
List names = new ArrayList();
names.add("a");
String s = (String) names.get(0); // synthetic cast inserted
// Consequences:
names instanceof List<String> // compile error — no runtime type
new T() // impossible — T doesn't exist at runtime
void f(List<String> l) {}
void f(List<Integer> l) {} // clash: same erased signature- Workarounds seniors know: pass
Class<T>tokens (T create(Class<T> type)), use super-type tokens (new TypeReference<List<Foo>>() {}— Jackson) which survive viagetGenericSuperclass(), orConstructor<T>references. - Bridge methods: the compiler generates synthetic methods so overriding works across erased signatures — occasionally visible in stack traces and reflection.
- Arrays vs generics:
new T[10]is illegal; the idiom is(T[]) new Object[10]confined inside the class (asArrayListdoes).