CheckedCollection 是 Collections.checkedXXX() 返回的运行时类型安全包装类,通过在 add/addAll/set 等写操作前用 instanceof 校验元素类型,非法时立即抛 IllegalArgumentException,从而拦截泛型擦除后错误插入的问题。

CheckedCollection 并不是 Java 标准库中一个独立的类或接口,而是 Collections.checkedXXX() 系列工厂方法所返回的**包装类实例**——它们在运行期对集合操作进行类型检查,防止向泛型集合中插入错误类型的元素。
它解决什么问题?
Java 的泛型是“类型擦除”的,编译后泛型信息不保留。这意味着:
- 通过反射、原始类型(raw type)引用、或非泛型代码,仍可能向
List中加入Integer; - 这种错误不会在编译时报错,而是在运行期引发
ClassCastException(通常在取值时才暴露,难以定位)。
Collections.checkedList(list, String.class) 这类方法,就是在集合的 add、addAll、set 等写入操作上,**实时校验待插入对象是否可赋值给声明的泛型类型**,立即失败,便于快速发现问题。
怎么用?关键三步
以 List 为例:
-
第一步:创建底层实际存储的集合(可以是任意实现,如
new ArrayList()); -
第二步:用
Collections.checkedList(底层集合, String.class)包装; - 第三步:只通过该包装引用操作集合(避免绕过检查,例如不要把底层集合再暴露出去)。
示例:
List<string> safeList = Collections.checkedList(new ArrayList(), String.class);
safeList.add("OK"); // ✅ 通过
safeList.add(123); // ❌ 抛出 ClassCastException(不是运行时 ClassCastException,而是 IllegalArgumentException)
</string>
注意:抛出的是 IllegalArgumentException(带明确提示),而非 ClassCastException,这是 checked 集合的设计选择。
支持哪些集合?有哪些限制?
标准 API 提供了以下 checked 包装器:
-
checkedList、checkedSet、checkedSortedSet、checkedNavigableSet; -
checkedMap、checkedSortedMap、checkedNavigableMap; - 所有方法都要求传入具体的
Class(不能是类型变量或通配符)。
重要限制:
- 仅检查**写入操作**(add / put / set / addAll 等),不检查读取;
- 不保护迭代器的
remove()(但 remove 本身不涉及类型插入,一般安全); - 若集合被其他未检查的引用访问(比如保留了原始 list 引用),检查即失效;
- 对数组、Stream、第三方集合(如 Guava)无效,需自行封装或选用其他方案(如不可变集合 + 构造期检查)。
它和现代替代方案怎么选?
CheckedCollection 是 JDK 1.5 就引入的老机制,如今更推荐组合使用:
- 优先用
ImmutableList.of()、ImmutableSet.copyOf()(Guava)或List.of()(JDK 9+)——构造即冻结,天然杜绝误写; - 需要可变集合时,配合严格的封装(private 字段 + 不返回内部引用)+ 单元测试覆盖非法插入场景;
- 在调试、测试或遗留系统集成中,
checkedXXX仍是低成本启用运行期类型防护的快捷方式。
它不改变泛型本质,也不修复擦除,只是加了一层“守门人”。用得恰当,能显著提升集合操作的健壮性。










