EnumMap 的 put 方法在运行时通过 key.getClass() == keyType 严格校验 key 是否为构造时指定的枚举类,不匹配则立即抛 ClassCastException;不检查枚举常量合法性,也不接受 null 或非枚举类型。

当你创建一个 EnumMap 时,必须指定其键的枚举类(如 new EnumMap<color string>(Color.class)</color>),这个类型信息会被保存在 map 内部。后续调用 put(K key, V value) 时,EnumMap 会通过 key.getClass() == keyType 做严格判断 —— 这里 keyType 就是构造时传入的枚举类对象。
校验发生在运行时,但只检查是否为同一枚举类
注意:它不会检查 key 是否属于该枚举类的某个合法常量(比如你传一个反射生成的、同名但不同类的枚举实例,仍会失败);它只做类对象的精确匹配。
- 合法:传入
Color.RED(前提是 map 声明为EnumMap<color ...></color>) - 非法:传入
Size.SMALL(即使Size也是枚举,但和 map 的 keyType 不一致) - 非法:传入
null(直接抛NullPointerException) - 非法:传入非枚举类型(如
"RED"或new Object())→ 抛ClassCastException
异常类型和触发时机很明确
put 在发现 key 类型不匹配时,会在方法入口处立即抛出 ClassCastException,堆栈中通常能看到 EnumMap.typeCheck 调用。
- 不是返回 false 或静默忽略
- 不是延迟到 get 或迭代时才报错
- 异常信息一般为:
java.lang.ClassCastException: class XXX cannot be cast to class YYY
开发者无需额外校验,但要注意泛型擦除的假象
虽然声明是 EnumMap<color string></color>,但泛型仅用于编译检查。真正起作用的是构造时传入的 Color.class。所以:
立即学习“Java免费学习笔记(深入)”;
- 不要试图绕过泛型传其他枚举值 —— 运行时立刻失败
- 避免使用原始类型(如
new EnumMap(...)不带泛型),否则编译器无法帮你提前发现问题 - 如果 key 来自外部(如反序列化、反射调用),务必确保其 class 对象与 map 的 keyType 完全一致
想提前拦截?只能靠你自己做类型判断
EnumMap 不提供 isValidKey 这类 API。若需防御性编程,可手动比对:
if (key != null && key.getClass() == enumMap.keyType()) { ... }- 或者更稳妥地:用
enumMap.keyType().isInstance(key)(支持子类场景,但枚举不能继承,所以等价)


















