只需提供public getter、不提供public setter并将字段设为private,即可构建只读实体类;需防御性拷贝可变引用类型,并在构造时初始化final字段。

只需为字段提供 public getter、不提供 public setter,并将字段设为 private,就能快速构建只读实体类。核心是控制访问权限,而非依赖复杂工具或注解。
字段必须声明为 private
这是只读封装的基础。即使有 getter,如果字段本身可被外部直接访问(如设为 public 或 protected),就失去了封装意义。
- 正确写法:private String name;
- 错误写法:public String name; 或 protected int id;
只暴露 public getter,不提供 public setter
getter 方法需为 public,命名遵循 JavaBean 规范(如 getName()、isAvailable());setter 方法要么完全不写,要么设为 private/protected(极少需要)。
- 推荐:只写 getter,不写 setter
- 避免:写一个空的或抛异常的 public setter(易误导调用方)
- 示例:
public String getName() { return name; }<br>public boolean isActive() { return active; }
注意不可变性陷阱:getter 返回引用类型时要防御性拷贝
如果字段是可变对象(如 ArrayList、Calendar、自定义 POJO),直接返回原引用会破坏只读性——外部仍可修改其内部状态。
- 对 List:返回 Collections.unmodifiableList(list) 或新建不可变副本
- 对 Date:返回 new Date(date.getTime())
- 对自定义对象:若该对象本身可变,考虑返回深拷贝或只读包装(如使用 record 或不可变 builder)
构造时完成初始化,禁止后续修改
所有字段应在构造方法(或静态工厂方法)中一次性赋值,且不提供任何修改状态的入口。可配合 final 字段进一步强化语义:
- private final String name;(推荐,编译期保证不可重赋值)
- 构造方法中完成全部字段初始化,不依赖 setter 或后期配置
- 若需延迟计算某些值,可在 getter 中惰性初始化(但确保线程安全)










