Collections.checkedList returns a backed view that rejects inserts of the wrong runtime element type through that view.
Java checkedList on LinkedList: runtime checks at a raw boundary
Guard the boundary that receives raw values
A legacy plugin exposes a raw List. Its attempt to insert an Integer through the checked view throws ClassCastException immediately, where the bad value enters. The original LinkedList still accepts valid strings and the view reflects them because it is backed by the same list.
The guard is not a copy and cannot protect the underlying list if some caller still holds a direct reference. It checks runtime classes on attempted writes through the wrapper; generic type parameters alone are erased. Generics explains compile-time checking, while backed views explains ownership.
Do not treat this as data validation
A String can still contain an invalid receipt identifier. Validate domain rules separately. A checked list also does not deeply inspect mutable elements or make access thread-safe.
Working program
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class CheckedReceiptBoundary {
@SuppressWarnings({"rawtypes", "unchecked"})
public static void main(String[] args) {
LinkedList<String> receipts = new LinkedList<>();
List<String> checked = Collections.checkedList(receipts, String.class);
List legacyPlugin = checked;
try { legacyPlugin.add(41); }
catch (ClassCastException rejected) { System.out.println("wrong runtime type"); }
checked.add("R-41");
System.out.println(receipts);
}
}Output
wrong runtime type
[R-41]Costs and boundaries
The wrapper delegates to the backing list and adds a runtime type check on its write paths. It does not deep-copy n elements, isolate callers holding the backing list, or validate receipt syntax.
Common Mistakes
- Do not expose the unwrapped list to code expected to respect the guard.
- Do not confuse a String type check with receipt-format validation.
- Do not assume a checked view is immutable or synchronized.
Read next
Java generics: invariance, bounds, and type erasure, Java collection views: live wrappers, snapshots and shallow copies, Java LinkedList: operations, internals and failure cases.
