EnumMap 实现业务类型多态分发,以枚举为键、策略对象为值,通过数组索引 O(1) 直取,零哈希、零装箱;需定义真实枚举类保障类型安全,声明顺序决定 ordinal;支持嵌套 EnumMap 实现双维度分发;初始化后应设为 final 保证线程安全。

用 EnumMap 实现业务类型多态分发,核心是把“类型判断 + 行为路由”从 if-else 或 switch 搬到数据结构里——用枚举做键、用策略对象做值,靠数组索引直取,零哈希、零装箱、O(1) 响应。
明确业务类型枚举,作为分发入口
先定义一个干净的业务类型枚举,每个常量代表一类可被分发的场景。例如订单系统中:
- 必须是真实枚举类:不能用字符串或整数代替,类型系统会保障 key 合法性;
- 顺序即语义:声明顺序决定内部数组下标(ordinal),也影响遍历时的自然顺序;
- 禁止 null 或非法实例:传 null 键直接抛 NullPointerException,非该枚举实例触发 ClassCastException。
示例:
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
用 EnumMap 绑定策略,避免运行时分支
声明 EnumMap<biztype bifunction config result>></biztype> 这类泛型映射,把每种业务类型的处理逻辑封装为函数式接口实例:
- 初始化时一次性注册全部策略,如
handlers.put(BizType.PAYMENT, this::handlePayment); - 执行时只靠
handlers.get(type).apply(ctx, cfg)一次查表+调用,无条件跳转; - 相比反射或 if-else 链,省去字符串匹配、类型检查、方法查找等开销。
支持嵌套分发:双维度决策更自然
当需要按「业务类型 + 状态」组合决策(如支付中不同状态走不同风控路径),可用嵌套 EnumMap:
- 外层:
EnumMap<biztype enummap handler>></biztype>; - 初始化时填满合法组合,如
matrix.get(PAYMENT).put(PENDING, new PreAuthHandler()); - 运行时两级 get 即得精准处理器:
matrix.get(biz).get(status).execute(); - 比二维 switch 或 Map
更类型安全、内存紧凑、访问更快。
注意线程安全与生命周期管理
EnumMap 本身非线程安全,但多数分发器是只读初始化后长期复用的:
- 推荐在 Spring Bean 初始化或静态块中构建并设为 final;
- 若需运行时动态增删(如热更新策略),加读写锁或用 CopyOnWriteArrayList 包装视图;
- keySet() 返回的是 EnumSet 视图,不可 add/clear,要复制再操作:
new ArrayList(map.keySet())。


















