用泛型方法+Lambda替代switch,核心是构建类型安全的函数映射Map,通过泛型接口约束I/O类型、ConcurrentHashMap注册分支、泛型dispatch方法自动推导类型,支持枚举/字符串key、异常统一处理及多参数扩展。

直接用泛型方法 + Lambda 表达式替代 switch,核心是把“分支逻辑”变成“可注册、可复用、类型安全的函数映射”,既消除了硬编码 case,又避免了反射或枚举的冗余结构。
定义统一的泛型分发接口
先创建一个函数式接口,承载任意输入、任意输出、任意异常的业务逻辑:
-
Function
适合无异常、单入单出场景(如状态转换、字段计算) - 自定义泛型接口更灵活,例如:
interface Handler<i o e extends exception> { O handle(I input) throws E; }</i> - 关键点:泛型参数 I 和 O 明确约束输入输出类型,编译期就能校验,不靠运行时 if 判别
用 Map 替代 switch 的 case 分支
把每个业务分支封装成一个 Lambda,按 key(如字符串命令、整数类型码、枚举值)存进 ConcurrentHashMap:
- 初始化时集中注册:
handlers.put("PAY", (Order o) -> paymentService.process(o)); - 执行时一行调用:
handlers.getOrDefault(type, fallbackHandler).apply(order); - 新增分支只需加一行 put,不改原有方法体,彻底解耦
- key 类型建议用枚举(类型安全)或常量字符串(便于配置化),避免魔法值
结合泛型方法实现类型推导与自动适配
写一个泛型分发方法,让调用方几乎感知不到类型转换:
- 声明:
<i o> O dispatch(String type, I input, Function<i o> fallback)</i></i> - 内部自动从 handlers 中取对应 Function,并 apply 输入,返回结果
- 调用时类型由 input 和 lambda 主体自动推导:
String result = dispatch("NOTIFY", emailDto, d -> "default"); - 如果 handler 抛异常,可在泛型方法内统一 try-catch 包装成业务异常,不暴露底层细节
进阶:支持多参数与上下文注入
纯 Function 只接受一个参数,实际业务常需多个输入或依赖服务。可用以下方式扩展:
- 封装参数对象:
record DispatchContext(Order order, User user, Config cfg) {},再用Function<dispatchcontext result></dispatchcontext> - 用 Lambda 捕获外部服务:
(ctx) -> notifyService.send(ctx.order, ctx.user),符合 effectively final 规则即可 - 配合 Spring,可将 handler 注册为 @Bean,用 @Qualifier 按 type 名称注入,实现配置驱动


















