Setter 是对象状态合法性的第一道守门人,需前置校验、语义一致、明确报错并预留扩展空间。

Setter 方法不是简单地“赋个值”,而是对象状态合法性的第一道守门人。真正体现面向对象设计价值的,是在 set 过程中嵌入业务规则与数据约束,让对象从创建到销毁始终处于可预期、可信赖的状态。
校验逻辑必须前置在赋值之前
很多初学者把校验写在赋值之后,或漏掉边界判断,导致非法值已写入字段,再抛异常也于事无补。正确顺序是:接收参数 → 验证合法性 → 通过才赋值。
- 年龄不能为负数,也不能超过 150(医学常识+系统可维护性)
- 邮箱必须符合正则格式,且自动转小写存储,避免后续比对失败
- 状态字段如 status 只允许预设枚举值("active", "inactive", "pending"),拒绝任意字符串
类型与语义必须严格匹配
Setter 的参数类型要和 getter 的返回类型一致,不只是语法层面,更是语义层面的一致。比如一个表示“金额”的字段,setter 接收 BigDecimal,getter 就不该返回 double —— 后者会丢失精度,破坏金融场景下的逻辑一致性。
- 避免隐式类型转换带来的歧义(如传入字符串 "123" 给 int 类型 setter)
- 若需兼容多种输入,应在 setter 内部做显式解析并校验,而非依赖 JVM 自动转型
- 现代 IDE 和 Lombok 的 @Data 默认不处理校验,需手动增强或改用 @Setter + 自定义逻辑
校验失败应明确反馈,而非静默忽略
静默丢弃非法值看似“友好”,实则掩盖问题,让调用方误以为设置成功。真实项目中,应统一使用有意义的异常,并附带上下文信息。
- 抛出 IllegalArgumentException 而非通用 RuntimeException
- 错误消息包含字段名、非法值、合法范围,例如:"age must be between 0 and 150, but got -5"
- 对关键业务字段(如用户身份证号、订单金额),还可记录日志或触发告警
结合封装机制,为扩展留出空间
Setter 不只是校验入口,也是行为注入点。未来可能需要加审计日志、触发事件通知、联动缓存更新等,这些都依赖 setter 的存在和可控性。
- 不要绕过 setter 直接修改私有字段(包括在类内部),否则校验逻辑形同虚设
- 子类重写父类 setter 时,应先调用 super.setXxx() 再追加逻辑,保证基础约束不被跳过
- 使用 Lombok 时,@Setter 注解无法内置校验,建议搭配 @Accessors(chain = true) + 手动重写关键 setter

















