java封装中setter方法必须在赋值前校验合法性并抛异常,构造器也需复用相同校验逻辑,确保对象始终处于有效状态。

在 Java 中,封装的核心之一是通过 setter 方法对属性赋值前进行合法性校验,确保对象状态始终有效。这不是简单地“设值”,而是把校验逻辑嵌入到赋值入口,让属性只能被合法、有意义的值修改。
校验时机:在赋值前拦截非法输入
setter 方法是外界修改私有属性的唯一受控通道。所有校验必须放在 field = value 这一行之前,否则无效。一旦发现非法值(如 null、负数、超长字符串),立即抛出异常(常用 IllegalArgumentException),阻止赋值发生。
- 校验失败不静默忽略,也不返回 false —— 异常能明确中断流程,避免后续逻辑基于错误状态运行
- 异常消息应具体,例如
"age must be between 0 and 150",方便调用方定位问题
常见校验类型与写法示例
根据属性语义选择校验方式,不追求“全检查”,只检查业务关键约束:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
非空校验:
if (name == null || name.trim().isEmpty()) throw new IllegalArgumentException("name cannot be blank"); -
数值范围校验:
if (age 150) throw new IllegalArgumentException("age must be between 0 and 150"); - 格式校验(如邮箱):可用正则或第三方库(如 Apache Commons Validator),但避免在 setter 中做耗时解析
-
依赖性校验:例如
startDate和endDate,可在setEndDate()中检查endDate.after(startDate)
避免副作用与性能陷阱
setter 是轻量级入口,校验逻辑需简洁可靠:
- 不调用外部服务、数据库或复杂计算 —— 这会让 setter 变慢且难以测试
- 不修改其他字段或触发事件 —— 保持单一职责,赋值就是赋值
- 字符串校验优先用
trim()再判空,避免因空格导致误判 - 对引用类型(如集合)做防御性拷贝,防止外部修改影响内部状态
配合构造器,形成完整防护
仅靠 setter 不够 —— 对象可能通过构造器直接初始化非法状态。因此,构造器中也应复用相同校验逻辑(可提取为私有校验方法),保证无论哪种创建方式,对象从诞生起就合法。
- 例如将校验抽成
private void validateAge(int age) { ... },在构造器和 setter 中都调用它 - 这样既避免重复代码,又统一了规则出口,便于后期维护和扩展
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










