用final修饰所有成员变量是实现不可变对象的必要条件,需配合private封装、不可变类型选择、构造器中初始化、无setter方法、防御性拷贝及类声明为final等约束。

在不可变对象(Immutable Object)设计中,用 final 修饰所有成员变量是基础但关键的一步——它保证引用不被重新赋值,是实现“状态不可变”的第一道防线。
必须用 private + final 修饰每个成员变量
成员变量不能是 public 或 protected,否则外部可直接修改;也不能是默认访问权限(包内可见),否则破坏封装性。同时必须加 final,否则构造完成后仍可能被意外重赋值。
- 基本类型(如 int、boolean):final 保证值不可变
- 引用类型(如 String、List、自定义对象):final 保证引用地址不变,但不阻止对象内部状态变化——所以引用的对象本身也得是不可变的(如用 String 而非 StringBuilder,用 Collections.unmodifiableList 包装 List)
初始化只能发生在声明处、实例初始化块或构造器中
final 实例变量不允许留空等待后续赋值。JVM 要求它在对象构造完成前就确定唯一值。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 推荐在声明时直接初始化(最简洁,如
private final String name = "Alice";) - 若需根据参数动态赋值,必须在所有构造器中显式赋值(每个构造器都要覆盖,不能漏)
- 也可在非静态初始化块中赋值,但不如构造器清晰,且多个构造器共用时易出错
禁止提供任何 setter 或可变行为的方法
即使字段全为 final,如果提供了修改内部对象状态的方法(比如返回一个可变集合并允许 add/remove),整个对象就不再是不可变的。
立即学习“Java免费学习笔记(深入)”;
- 只暴露 getter,且返回值要是不可变类型或防御性拷贝(如返回
new ArrayList(this.list)或Collections.unmodifiableList(this.list)) - 避免返回内部可变对象的原始引用
- 构造器中若接收可变参数(如传入 ArrayList),务必做深拷贝或包装,防止外部持有并修改原始对象
配合其他约束才能真正不可变
final 成员变量只是必要条件,不是充分条件。还需:
- 类本身用 final 修饰(防止子类通过继承绕过封装,添加可变字段或方法)
- 所有字段类型本身是不可变的(如 String、LocalDateTime、Integer),或确保其可变字段也被 final + private + 正确初始化
- 重写
equals()和hashCode()(便于安全用于集合和比较)

















