java封装防非法修改的核心是private切断直连、setter嵌入校验、getter返回不可变视图、构造器兜底合法、final锁定终值。

Java 中封装限制属性非法修改,核心是切断直接访问路径、控制进出逻辑、堵住常见篡改出口。
用 private 锁死字段入口
所有业务关键属性(如余额、状态码、权限等级)必须声明为 private:
- 外部类无法通过
obj.amount = -100直接赋值,连编译都过不去 - 反射访问需显式调用
setAccessible(true),而该操作可被SecurityManager拦截或日志审计 - 避免使用
protected或包级默认访问——它们在子类或同包下仍可能被绕过
setter 方法中嵌入校验逻辑
不是简单赋值,而是把业务规则写进 setter:
- 对数值型字段检查范围:例如
setAge(int age)要求age >= 0 && age ,非法值抛 <code>IllegalArgumentException - 对字符串字段判空、长度、格式:比如
setEmail(String email)需验证是否符合邮箱正则,且不为 null 或空白 - 敏感字段禁止明文 setter:如密码字段不提供
setPassword(String),只提供changePassword(PlainPassword, HashedSalt)这类带加密流程的语义化方法
getter 返回不可变视图,防“出口污染”
不让外部拿到原始引用,避免通过返回值反向篡改内部状态:
- 集合类字段(
List<role></role>、Map<string config></string>)的 getter 不返回原对象,改用Collections.unmodifiableList(roles)或ImmutableList.copyOf(roles) - 数组字段返回副本:
return Arrays.copyOf(this.permissions, this.permissions.length) - 自定义对象类型(如
User)本身也应是不可变的:字段全private final,无 setter,构造器完成全部初始化
构造器阶段就做合法性兜底
对象一旦创建,内部状态就必须合法——不能依赖后续 setter 补救:
- 在构造器中对所有参数做完整校验,例如
new Order(null, -50.0)应直接抛异常,而不是允许对象处于非法初始态 - 若字段有默认值,应在构造器内统一设置,而非靠字段声明时初始化(后者无法参与校验)
- 配合
final字段使用:确保校验通过后值不可再变,从语法层面杜绝后续覆盖
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











