对象创建阶段应拦截非法状态:在构造函数中校验参数合法性并抛异常,禁止危险操作,封装资源失败语义,复杂场景用静态工厂方法替代。

在对象创建阶段就拦截非法业务状态,核心思路是:把校验逻辑前移到构造函数里,一旦发现不合法参数或环境,立即抛出异常,阻止对象实例化。这样能从源头杜绝“半成品”对象被误用。
校验关键参数是否合法
构造函数是对象生命周期的起点,也是唯一能确保所有字段都按预期初始化的地方。对必填字段、取值范围、格式等做严格检查:
- 用 IllegalArgumentException 处理业务规则类错误,比如年龄为负、ID为空、金额超限
- 用 NullPointerException 检查不可为空的引用类型(Java 8+ 可配合
@NonNull注解增强语义) - 避免只做“非空”判断而忽略深层合法性,例如 URL 字符串非空,但协议不支持或端口无效,也应在此刻拒绝
拒绝危险初始化行为
有些操作一旦执行,即使后续抛异常也无法撤回,比如启动线程、发布 this 引用、写入外部系统。这些必须禁止出现在构造函数中:
- 不要在构造函数里调用可被子类重写的方法(可能访问未初始化字段)
- 禁止在构造中暴露未完成对象,如
new Thread(() -> System.out.println(this)).start() - 若需异步初始化,改用工厂方法 + 显式
init()或 CompletableFuture 延迟触发
封装资源获取失败的语义
当对象依赖外部资源(数据库连接、配置文件、网络服务),不应让构造函数静默失败或返回 null。要让失败“可见且可处理”:
- Java 中可声明
throws IOException, SQLException,由调用方决定重试、降级或告警 - 更推荐自定义受检异常,如
ConfigLoadException,比泛化的Exception更具业务含义 - 避免包装成
RuntimeException后完全甩给上层——除非该错误确实代表程序缺陷(如配置硬编码错误),而非运行时波动
用工厂方法补充构造函数的局限
纯构造函数难以支持复杂校验流程(如查数据库确认 ID 唯一性)或需要清理中间状态的场景。此时应退一步,用静态工厂方法:
- 方法名可表达意图,如
User.createVerified(String email) - 内部可做多步验证,任一步失败都返回明确错误,不产生中间对象
- 便于统一处理日志、指标、事务边界,也利于单元测试模拟失败路径










