An unchecked cast converts between parameterized generic types when the conversion cannot be verified at run time. Java erases type arguments, so the virtual machine sees `List`, not `List<String>` or `List<Object>`. The cast may therefore vanish from bytecode while the compiler emits an Unchecked Cast warning. section 5.3.2 section 5.5
A delayed ClassCastException
A `List<String>` can be viewed as `List<?>` and then unsafely cast to `List<Object>`. Adding an `Integer` succeeds because the runtime list has no retained element-type information. The list is corrupted, but failure is delayed until code reads an item as `String`; the compiler-inserted cast on `get()` then throws `ClassCastException`. section 5.3.2
List<String> list = new ArrayList<>(); List<?> objects = list; ((List<Object>) objects).add(1); #1 printFirstItem(list);
This short sequence isolates the time bomb: the unchecked cast permits an incompatible write, while `printFirstItem` fails only on its later typed read. section 5.3.2
Do not treat `List<String>` as `List<CharSequence>` merely because `String` implements `CharSequence`: a mutable callee could add another `CharSequence`, such as a `StringBuilder`. Prefer a wildcard when the callee only needs to read values, for example `List<? extends CharSequence>`. When mutation must be prevented, pass an unmodifiable wrapper instead of forcing a cast. section 5.3.2 section 5.5
Avoid unchecked casts with these rules:
- Keep the declared type as specific as the actual value when possible, eliminating an unnecessary cast. section 5.5
- Use wildcard types to express safe producer-style reads rather than casting between invariant generic collections. section 5.3.2
- Use read-only or write-only wrappers where the required operation permits them, rather than exposing a mutable collection through an unsafe type. section 5.3.2 section 5.5
- Treat the compiler warning as a delayed-failure risk: the eventual exception can occur far from the cast and be harder to debug. section 5.3.2 section 5.5

