java防止外部直接修改类属性的核心是封装:将属性设为private封死访问通道,再通过带校验的setter、只读getter(含不可变视图/副本)及final锁定等手段实现受控读写。

Java 防止外部直接修改类属性,核心是靠封装——把属性设为 private,再通过受控的访问方式管理读写。这不是加个修饰符就完事,关键在“怎么控”和“控什么”。
用 private 封死直接访问通道
所有需要保护的字段都必须声明为 private,这是第一道防线。哪怕只是临时变量、配置项或集合容器,只要不希望外部绕过逻辑直接改,就得私有化。
-
private String name;—— 外部连点号都点不到 -
private List<item> items;</item>—— 即使是集合,也不能让别人 add/remove -
private final BigDecimal balance;—— 加final进一步锁定不可变性
getter 不等于“放行”,而是“只读出口”
提供 getter 是为了读取,不是为了开放修改权。尤其对引用类型,不能直接返回原始对象。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 基本类型或不可变对象(如
String、Integer):直接返回值即可 - 可变集合(
List、Map等):用Collections.unmodifiableList(items)包一层,返回只读视图 - 自定义对象:如果该对象本身可变,getter 应返回副本(如
new Person(this.person)),而非原引用
setter 要带校验,不是“传啥存啥”
setter 是唯一允许修改的入口,必须承担数据合法性把关责任。
- 检查空值:
if (name == null || name.trim().isEmpty()) throw new IllegalArgumentException("Name cannot be blank"); - 检查范围:
if (age 150) throw new IllegalArgumentException("Invalid age"); - 检查状态约束:比如账户余额不能设为负数,订单状态只能从“待支付”转为“已支付”,不能跳转
- 敏感字段(如密码)可只提供 setter,不提供 getter
对构造即定型的数据,干脆去掉 setter
有些属性只应在创建对象时设定,之后绝不允许变更——比如用户 ID、订单编号、创建时间。
- 声明为
private final - 只在构造器中初始化
- 不提供对应 setter 方法
- 必要时配合私有数据类(Private Class Data 模式),把整组只读状态抽成独立类,主类只持有一个不可变引用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










