Short answer
Generics are a compile-time-only feature: the compiler erases type parameters to their bounds (or Object) and inserts casts, so at runtime List<String> and List<Integer> are the same class.
Explanation
Consequences are you can't do new T[], can't use instanceof List<String>, can't catch a generic exception type, and overloads that differ only by type parameter clash. The workarounds are passing a Class<T> token (Class.cast / Array.newInstance) or capturing the type with a super-type token (the TypeReference pattern Jackson uses).
Common mistakes
- Expecting to do new T() or instanceof List<String> at runtime.
- Forgetting a Class<T> token or super-type token works around erasure.