Collections.checkedMap仅在写操作时校验键值类型,不追溯检查已有数据、不校验读取操作、不保证嵌套结构安全,且需避免底层map被直接访问。

Collections.checkedMap 并不“强制执行”运行时的键值类型检查,而是**在插入或更新操作时,对传入的键和值进行一次类型校验**,如果类型不匹配,立即抛出 ClassCastException。它不会对已存在的、类型错误的数据做追溯检查,也不会在读取(如 get)时再次校验。
它只在写操作时做类型守门
checkedMap 包装一个已有 map(如 HashMap),并在其 put、putAll、compute 等修改方法中插入类型检查逻辑:
- 每次调用
put(K key, V value),会先检查key是否可赋值给声明的键类型(如String.class),value同理 - 若类型不符(例如向
checkedMap<String, Integer>中put(123, "abc")),立刻抛异常,map 不变 - 但一旦非法数据通过其他方式(如绕过 checkedMap 直接操作底层 map)进入,checkedMap 无法感知,后续
get返回该值时也不会报错
不能替代泛型的编译期安全
泛型(Map<String, Integer>)只在编译期提供类型约束,运行时被擦除;checkedMap 是运行时补充防护,二者定位不同:
- 编译器能阻止
map.put(42, "hello")(如果 map 声明为Map<String,Integer>且你没用原始类型) - checkedMap 主要防范反射、反序列化、遗留 raw-type 代码等绕过编译检查的场景
- 它不解决类型擦除问题,也不增强
get的返回类型安全性(仍需手动强转或依赖泛型推导)
使用时要注意包装时机和底层引用
常见误用是未切断对原始 map 的访问:
- 必须用
Collections.checkedMap(originalMap, K.class, V.class)创建,并**只通过该包装引用操作** - 如果还保留着 originalMap 的引用,并直接往里面 put 非法类型,checkedMap 完全无感
- 推荐搭配不可变视图或私有封装(如放在 private final 字段中,只暴露 checked 引用)
它不检查嵌套结构或运行时类型变化
checkedMap 只校验参数本身的运行时类,不深入检查:
- 若键类型是
List<String>,它只检查传入对象是否为List实例,不验证 list 元素是不是String - 若值是自定义类,它只检查是否为该类或其子类,不校验字段内容或内部状态
- 不支持通配符或复杂类型变量(如
? extends Number),构造时必须传具体Class对象

















