静态工厂方法可通过复用不可变业务异常、延迟初始化、享元缓存及避免运行时new等方式减少异常创建开销。

静态工厂方法本身不负责“创建异常”,但如果你指的是“用静态工厂方法来减少异常对象的创建开销”,那关键在于:**避免在高频路径上反复 new 异常实例,而改用复用、缓存或延迟构造的方式**。
静态工厂方法可复用不可变异常实例
Java 中多数标准异常(如 IllegalArgumentException、NullPointerException)是可变的(因为它们持有堆栈跟踪),但若你自定义的是**无堆栈、轻量、不可变的业务异常**,就非常适合用静态工厂复用:
- 定义一个 final static 异常实例,通过静态工厂方法统一返回,比如
MyBizException.alreadyExists() - 该方法内部不 new,而是直接返回预创建好的单例对象(类似
Boolean.TRUE) - 适用于语义固定、无需携带动态上下文的场景,例如“资源已存在”“参数非法”等通用错误码
避免在日志或校验中无谓 new 异常
很多开发者会在 if 判断后直接 throw new XxxException("..."),看似简洁,实则每次都会分配异常对象并填充堆栈——这对高频调用(如参数校验入口)开销明显:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 把异常创建移到静态工厂中,并结合 lazy 初始化:首次调用才构建,后续复用
- 对不需要完整堆栈的场景(如断言失败),可用
Objects.requireNonNull(obj, msg),它抛出的 NPE 是 JVM 优化过的,开销更低 - 若必须带动态信息(如 ID、时间),优先拼接 message 字符串,而非塞进异常构造器;构造器里做字符串拼接会额外触发 StringBuilder 分配
用 Error/RuntimeException 子类 + 静态工厂组合享元模式
对于需区分类型但内容高度重复的异常(如不同字段的校验失败),可设计带 key 的享元工厂:
立即学习“Java免费学习笔记(深入)”;
- 维护一个
ConcurrentHashMap<string myvalidationexception></string>,key 是标准化错误码(如"user.email.invalid") - 静态工厂
of(String code, Object... args)先查缓存,命中则填充 message 后返回(不 new 异常对象) - 未命中时 new 一次并缓存,同时限制缓存大小或使用弱引用,防内存滞留
慎用 try-catch 包裹静态工厂调用
如果静态工厂方法内部可能抛异常(比如解析配置失败),不要让它成为 new 异常的源头:
- 把易错逻辑提前到初始化阶段(如 static 块中加载),让工厂方法保持纯函数性、零异常
- 若必须运行时检查,优先返回
Optional<Result>或Result<T, E>类型,把异常封装为值对象,避免 JVM 抛出成本 - 避免在工厂里写
try { return new X(); } catch (Y e) { throw new Z(); }—— 这等于用一次 new 换另一次 new,没省开销

















