优雅处理“不支持的操作”应避免抛异常,而用多态消解条件判断:采用接口+空对象、抽象基类封装支持性判定、策略模式动态适配、语义化异常包装。

Java 多态实战中优雅处理“不支持的操作”,关键不是强行让所有子类都实现所有方法,而是通过设计让“不支持”本身成为可预期、可管理、无需层层判空的行为。核心思路是:用多态消解条件判断,用契约明确行为边界。
用接口+空对象替代“抛异常”的粗暴方式
当某个子类确实不该支持某操作(比如只读策略不支持 save()),与其在方法里 throw new UnsupportedOperationException(),不如让该子类返回一个“空对象”或委托给专用的 NullHandler。
- 定义统一接口(如 Exporter),包含
export()和cancel() - 对只读导出器,实现
cancel()时返回一个 NullCanceler 实例,其cancel()方法为空操作或记录日志,不抛异常 - 调用方始终面向接口编程,无需 instanceof 或 try-catch,行为自然收敛
在抽象基类中封装“是否支持”的判定逻辑
避免每个子类重复写 if-throw,把支持性检查上提到父类,用模板方法控制流程。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在抽象类中定义
isCancelable()模板方法,默认返回 false,子类按需重写 -
cancel()方法为 final,内部先调用isCancelable(),为 false 时直接返回或走默认补偿逻辑(如打印 warn 日志),不再抛异常 - 既保持语义清晰,又防止误用,还利于统一监控(例如统计哪些 cancel 被静默忽略)
结合策略模式 + Spring 的自动装配规避硬编码判断
运行时动态选择行为,天然适配“部分类型支持、部分不支持”的场景。
立即学习“Java免费学习笔记(深入)”;
- 定义策略接口 PaymentStrategy,含
pay()和refund() - 为微信支付实现完整策略;为现金支付只实现
pay(),refund()方法直接返回 RefundNotSupportedResult 对象(含 code/message) - 通过 Spring 的
@Qualifier或 Map 注入,业务层按需获取策略,调用后统一处理结果对象,而不是 catch 异常
自定义 UnsupportedOperationException 的语义化包装
如果必须抛异常,就让它携带上下文信息,便于排查和监控。
- 不直接 throw new UnsupportedOperationException(),而是封装为 UnsupportedOperation(继承 RuntimeException)
- 构造时传入操作名、目标类型、触发上下文(如用户ID、订单号),并自动打点上报
- 配合全局异常处理器,对这类异常统一返回 400 + 友好提示,而非 500 内部错误

















