封装是数据隐藏、行为封装与接口暴露三者缺一不可的设计思想:用private隐藏字段和辅助方法,所有操作必须经类内方法并校验,仅暴露必要公共接口。

封装不是加个 private 再配两个 getXxx() 和 setXxx() 就算完事。它是一种设计思想,核心是“把该管的管住,该给的给清楚”——既不让外部随意碰内部数据,又提供安全、可控的交互方式。
封装的本质是三个动作缺一不可
只做其中一两步,封装就不到位:
-
数据隐藏:用
private把字段和辅助方法锁在类里,外部连读都读不到; - 行为封装:所有对字段的操作(哪怕只是赋值)都必须走类自己的方法,确保每次修改都经过统一逻辑(比如年龄不能为负、邮箱格式要校验);
-
接口暴露:只公开真正需要被调用的方法,比如
getName()、login(),而不是把所有内部工具方法都设成public。
标准实现步骤很明确
写一个类时,按顺序做这四件事:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 把所有字段声明为
private(姓名、年龄、账号等); - 为每个字段补上
public的 getter 方法(只读场景可省 setter); - 为需要修改的字段补上
public的 setter 方法,并在里面加校验(如if (score < 0 || score > 100) throw ...); - 把重复的校验、格式化、计算等逻辑抽成
private方法,在 setter 或业务方法里调用,不对外暴露。
常见误区要避开
这些做法看似封装,实则削弱了封装效果:
立即学习“Java免费学习笔记(深入)”;
- 字段设成
private,但 setter 里不做任何检查,等于“挂锁不设防”; - 把整个对象的内部状态通过
toString()或一个getDetailMap()全部吐出去,破坏了数据边界; - 为了图省事,把工具方法(如日期格式化、密码加密)设为
public static暴露出去,导致其他类绕过本类逻辑直接调用; - 在 getter 中返回可变对象的引用(比如
return list;),外部拿到后能直接修改原集合——应改为return new ArrayList(list);或返回不可变视图。
IDE 能帮但不能替你思考
IntelliJ 或 Eclipse 可一键生成 getter/setter,但生成只是起点:
- 自动生成的 setter 默认不带校验,你要手动加上业务规则;
- 有些字段不该被外部修改(如创建时间、订单号),就不该有 setter;
- 有些字段不该被外部读取(如密码密文),就不该有 getter;
- 如果类里有复杂状态流转(如订单从“待支付”到“已发货”),光靠字段 + setter 不够,得封装成
pay()、ship()这样的业务方法,把状态变更逻辑收拢在类内部。

















