Java封装核心是私有字段+受控getter/setter:字段一律private,慎用setter,优先final+构造器初始化;集合getter返回不可修改视图;record适合不可变DTO,Builder适用于复杂对象。

Java 封装设计中,避免直接暴露成员变量的核心是:用 private 修饰字段,并通过 public 的 getter/setter 方法 控制访问,同时在方法中加入逻辑校验与行为约束。
成员变量一律设为 private
这是封装的第一步,也是最基础的防线。任何本意不对外公开的字段(尤其是状态相关、影响对象一致性的)都应声明为 private。即使当前没有业务逻辑需要限制,也别用 protected 或包级默认权限“留后路”,否则后续重构成本高、易被子类或同包类意外修改。
- 反例:
public String name;或String email;(包内可直改) - 正例:
private int age;、private final List<String> tags = new ArrayList<>();
谨慎提供 setter,优先考虑不可变性
并非所有字段都需要 setter。若字段在对象创建后不应变更,就不要提供 public setter,而应在构造器中初始化——配合 final 字段更能保障线程安全和语义清晰。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 身份证号、订单 ID 等标识类字段通常只读,用构造器传入 + private final + 仅 getter
- 若需后期更新(如用户地址),setter 中应加入非空校验、格式验证(如邮箱正则)、或触发监听逻辑(如
fireAddressChanged()) - 集合类字段避免直接返回内部引用,getter 应返回不可修改视图:
Collections.unmodifiableList(tags)
getter/setter 不只是透传,而是控制点
这些方法不是摆设,而是封装真正的发力点。它们可以做数据转换、懒加载、访问审计、线程同步等。
立即学习“Java免费学习笔记(深入)”;
- 敏感字段(如密码)的 getter 可返回
"***"而非明文 - 计算型属性(如
getFullName())不必对应成员变量,而是实时拼接 - setter 中抛出
IllegalArgumentException比让调用方传错值后崩溃更友好 - 多线程场景下,简单字段的 getter/setter 若涉及共享状态,可用
synchronized或volatile协助保障可见性(但更推荐无状态或使用java.util.concurrent类型)
用记录类(record)或 Builder 模式简化安全封装
JDK 14+ 的 record 天然支持不可变封装:自动私有字段 + 公共只读 accessor + 结构化 equals/hashCode。适合 DTO、返回值等纯数据载体。
- 例如:
record User(String name, int age) {}—— name/age 不可变,且无 public 字段 - 复杂对象建议用 Builder 模式:构造过程集中校验,构建后返回不可变实例,避免半初始化对象泄漏

















