封装通过控制可见性、稳定对外契约、配合包结构及为JPMS导出铺路来支撑模块化,需分层落实类、包、模块三级封装并规避常见误区。

Java 封装是模块化开发的底层支撑,它让每个类成为可独立管控的“小模块”,从内部数据保护到接口边界定义,都为更高层级的模块化(如 JPMS)打下基础。
封装如何支撑模块化
模块化强调“高内聚、低耦合”,而封装正是实现这一目标的第一道防线:
-
控制可见性:用
private隐藏字段和内部方法,只通过public方法暴露必要行为,避免外部随意依赖实现细节; - 稳定对外契约:即使内部逻辑重构(比如把 age 存成字符串再解析),只要 getter/setter 接口不变,调用方完全无感;
-
配合包结构形成逻辑单元:同一包下的类天然共享
default访问权限,便于封装内部协作逻辑,同时对外统一由 public 类提供服务; -
为 JPMS 模块导出铺路:JPMS 要求模块明确
exports哪些包——而这些包里的类,必须已通过封装设计好公共 API,否则导出的就是一堆不可靠或不安全的接口。
怎么做:从类封装到模块封装
分两层落地,先做好类级封装,再升级为模块级封装:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
-
类层面:属性一律
private;提供带校验的 setter(如年龄不能为负、邮箱格式校验);getter 可按需返回副本(防止外部修改内部数组/集合);构造器优先调用 setter,确保初始化也走验证逻辑; -
包层面:按功能划分包(如
com.example.order.model、com.example.order.service);包内非 public 类和方法仅限本包使用,不对外暴露;避免跨包直接访问非 public 成员; -
模块层面(JPMS):在
module-info.java中只exports稳定的 API 包(如exports com.example.order.api),不导出impl或internal包;用requires显式声明依赖,杜绝隐式类路径耦合; -
工具辅助:启用编译器警告(如
-Xlint:serial)、静态检查(如 SonarQube 规则“Classes should not be exposed with public fields”),及时发现封装破绽。
常见误区提醒
封装不是加个 private 就完事,关键在“意图清晰”和“边界可控”:
立即学习“Java免费学习笔记(深入)”;
- 不要为所有字段机械生成 getter/setter,只暴露真正需要被外部读写的数据;
- 避免 public static final 字段直接暴露可变对象(如
public static final List<String> NAMES = new ArrayList<>();),应返回Collections.unmodifiableList(...); - 模块中导出的包,其 public 类不应依赖未导出包里的非 public 类型(否则编译或运行时报错);
- 测试代码(如 JUnit)属于模块外部,需通过 public API 测试,不能因方便而降级访问权限(如改成 package-private 来测私有方法)。
封装是模块化的起点,也是最常被轻视的一环。它不解决架构问题,但能让模块真正“立得住”。

















