Java封装数据校验的核心是setter中先检查后赋值,防止非法值污染对象状态;字符串需判空、trim、再验空;数值注意边界;集合需防御性拷贝;禁用assert,推荐IllegalArgumentException或Objects.requireNonNull;record构造器须全覆盖校验并不可变封装。

Java 中封装数据校验的核心,是在 setter 方法里“先检查、再赋值”,用 throw 主动拦截非法参数,防止对象状态被污染。
setter 里必须校验在前、赋值在后
这是最关键的顺序。一旦先执行 this.field = value,哪怕后续抛异常,非法值已经写进对象,破坏了封装性与数据完整性。
- ✅ 正确:检查通过才赋值 ——
if (age 150) throw new IllegalArgumentException("年龄必须在 0~150 之间"); this.age = age; - ❌ 错误:先赋值再校验 —— 状态已变,无法回退,违反封装原则
常见类型校验要点
不同数据类型有不同陷阱,校验不能只靠“看起来像”:
- 字符串:先判
null,再trim(),最后检查是否为空 —— 避免" "过检 - 数值:注意边界是否闭合(如年龄 ≤150 还是
- 集合类:若字段是
List或Map,校验非空后建议用List.copyOf(list)做防御性拷贝,防止外部修改内部状态
用对异常类型,别滥用断言
用户输入、API 参数、配置项等运行时可变数据,一律用显式 if + IllegalArgumentException(或自定义业务异常)。
立即学习“Java免费学习笔记(深入)”;
- ❌ 不要用
assert:它默认关闭,生产环境无效,且不适用于外部传参场景 - ✅ 推荐写法:
Objects.requireNonNull(name, "name 不能为空")(抛NullPointerException,语义更准);非 null 但需格式合法的,用IllegalArgumentException - 消息要具体,比如
"邮箱格式不合法: " + email,但避免拼接密码、token 等敏感内容
record 类的校验更需一步到位
record 的字段天然 final,构造器是唯一赋值入口。校验漏掉,对象就永远非法,无法补救。
- 校验必须覆盖所有非法组合,例如
name为空且age超限,要一并捕获 - 若 record 含可变对象(如
List<string></string>),构造器中不仅要校验非空,还要做不可变封装:this.tags = List.copyOf(tags) - 不要依赖“后面 setter 再修”——record 没 setter


















