Java封装核心是构建可落地、能防御、易演进的数据管控机制,要求字段私有化、构造器校验、不可变属性加final、getter/setter承载业务规则、集合与状态变更语义化、校验逻辑内聚复用。

Java 中封装和数据隐藏不是写几个 private 和 getter/setter 就算完成,而是在项目中形成一套可落地、能防御、易演进的数据管控机制。核心是让对象状态始终处于受控范围内,外部只能“申请操作”,不能“直接动手”。
字段私有化是底线,不是终点
所有业务敏感字段(如用户密码、账户余额、身份证号、订单状态)必须声明为 private。这不是形式主义,而是编译期防线——一旦有人写 user.password = "123",IDE 直接报错,连运行机会都不给。
- 连同构造器参数也走校验:比如创建
Order对象时传入负数金额或空收货地址,构造器就抛IllegalArgumentException,拒绝诞生非法对象 - 避免用
public或包级私有暴露字段,哪怕只是“临时调试用”,上线前必须清理 - 对不可变属性(如订单 ID、创建时间),加上
final并只提供 getter,从语义和语法双重锁定
getter/setter 是守门人,不是搬运工
公共方法是唯一合法入口,必须承载业务规则:
-
setPassword(String pwd)要校验长度、字符组合、是否为弱口令,并自动调用加密工具存哈希值;getPassword()永远返回"***",绝不吐明文 -
setIdCard(String card)内部做脱敏存储(如保留后四位),getIdCard()返回"**** **** **** 1234" -
setAge(int age)不只是判断正负,还要覆盖真实业务范围(如学生年龄 6–25,员工年龄 18–65),超限统一拒绝或转换为默认值
集合与状态变更必须语义化
避免外部拿到引用后随意增删改,破坏对象一致性:
立即学习“Java免费学习笔记(深入)”;
- 返回集合时用
Collections.unmodifiableList(orders)或ImmutableList.copyOf(orders),确保列表不可变 - 状态流转不开放字段赋值,例如订单不能
order.status = "SHIPPED",而要定义shipOrder()方法,内部自动检查是否已支付、生成运单、更新时间戳、触发消息通知 - 关联对象(如用户持有的银行卡列表)若需修改,提供
addBankCard(Card card)和removeBankCard(String cardNo),而不是暴露整个 List 引用
校验逻辑要内聚复用,别散落在各处
把重复判断抽成私有工具方法,保证规则统一、修复一处全量生效:
- 写一个
private boolean isValidPhone(String phone),统一处理空格、+86 前缀、11 位数字、正则匹配 - 构造器、setter、甚至接口层参数校验都复用它,避免前端传 "+86 138 1234 5678" 在 A 处通过、B 处失败
- 校验失败时不静默吞掉,明确抛出带业务含义的异常(如
InvalidMobileException),方便上层做差异化处理
不复杂但容易忽略:封装真正的价值不在“写得对”,而在“改得稳”——当某天身份证校验规则升级为含行政区划码校验,你只需改一个私有方法,所有用到它的类自动生效,调用方代码完全不用动。


















