封装的核心是用private堵死字段直访通道,强制业务校验;public仅暴露契约接口;getter/setter须带校验与脱敏;构造函数需首道守门。

Java 面试中问“访问修饰符怎么配合封装原则使用”,核心不是背权限表,而是讲清楚:为什么这么用、不这么用会出什么问题、实际代码里怎么落地。封装不是语法练习,是设计意识。
字段一律 private,堵死直接访问通道
这是封装的底线。任何业务相关的字段——账户余额、用户密码、库存数量、设备状态——都必须声明为 private。它不是“怕别人看到”,而是防止外部绕过校验逻辑随意赋值。
- 错误写法:
public double balance;→ 外部可直接写acc.balance = -999999;,系统瞬间失序 - 正确写法:
private double balance;→ 强制所有修改走deposit()或withdraw()方法,在里面做金额合法性判断 - 连“只读”字段也不能例外:比如身份证号,即使不打算改,也应
private final String idCard;+getIdCard(),避免未来被意外篡改
方法按职责定权限,public 只暴露契约接口
public 方法是类对外的“服务窗口”,只该提供明确、稳定、有业务意义的操作入口,而不是把内部工具方法全扔出去。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 业务操作方法(如
placeOrder()、cancelTicket())设为 public,但内部调用的校验、日志、补偿逻辑,统统 private - 子类需要扩展的行为(如图形类的
calculateArea()),用 protected,既保留继承灵活性,又防止无关类调用干扰 - 同包内协作的辅助类(如 DAO 工具类),可用默认(包级)修饰符,比 public 更安全,比 private 更实用
getter/setter 不是摆设,要带业务校验和防御逻辑
面试官常追问:“既然用了 private + getter/setter,那 setXXX() 里什么都不做,和 public 字段有区别吗?”答案是没有——封装就失效了。
立即学习“Java免费学习笔记(深入)”;
-
setPassword()必须检查长度、特殊字符、是否为空;setAge()必须限制在 0–150 范围 - 敏感字段(如银行卡号)的 getter 可做脱敏处理:
return cardNumber.replaceAll("(\d{4})\d{8}(\d{4})", "$1****$2"); - 不要为每个 private 字段机械生成 getter/setter。只暴露真正需要外部读写的属性;只读属性只给 getter;计算属性(如
getFullName())可不存字段,直接拼接返回
构造函数也要守门,确保对象一创建就合法
封装从对象诞生那一刻就开始。如果构造函数放任非法参数通过,后续所有保护都成空谈。
- 传入负数余额?抛
IllegalArgumentException - 传入 null 用户名?立即拦截,不等 setOwner() 再处理
- 必要字段缺失?用全参构造强制初始化,避免出现半成品对象
- 如需灵活构建,配合 Builder 模式,但 Builder 内部仍要复用相同的校验逻辑

















