Java包与访问修饰符协同实现分层可见性控制:包划定命名空间边界,private仅本类可见,default限同包,protected扩展至子类(含跨包),public全局可见,顶层类仅支持public或default。

Java 中包和访问修饰符共同构成一套分层可见性控制机制:包划定“地理边界”,访问修饰符定义“权限等级”,二者配合实现从类到成员的精细化封装。
包是可见性的第一道防线
包(package)本质是命名空间,用于组织和隔离代码。它不直接提供访问控制逻辑,但所有访问修饰符的生效范围都依赖于包结构:
- 包名需与目录结构一致,例如 com.example.service 对应 com/example/service/ 目录
- 不同包之间的类默认互不可见,哪怕类名相同也不会冲突
- import 语句只是简化类名书写,并不改变访问权限——即使导入了某个类,若其成员是 private 或 default,依然无法访问
- 模块化(Java 9+)进一步强化包边界,通过 module-info.java 显式导出(exports)包,未导出的包对外完全不可见
四种访问修饰符的实际作用域
修饰符的可见性不是孤立存在的,必须结合包和继承关系理解:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- private:仅限本类内部。子类、同包其他类均不可见。这是最强封装,适用于字段、辅助方法、内部状态管理
- default(无修饰符):同一包内所有类可见,无论是否继承。适合模块内部协作,比如 service 包里的多个服务类共享一个工具方法
- protected:本类 + 同包类 + 不同包子类(且只能通过 this 或 super 访问自身继承来的成员)。不能写 new Parent().field,哪怕在子类里也不行
- public:任何地方都可访问。只应用于明确承诺长期稳定的契约点,如接口方法、DTO 的 getter、工具类的静态方法
类本身也有访问限制
顶层类(非内部类)只有两种合法修饰符:
立即学习“Java免费学习笔记(深入)”;
- public:类名必须与文件名一致,且整个项目中任意位置都能 new 或引用
- default(包私有):仅同包内可用,常用于隐藏实现类(如 DefaultOrderService),避免被外部误用
- 不允许对顶层类使用 private 或 protected —— 编译直接报错
常见误区与关键细节
这些点容易被忽略,却直接影响设计合理性:
- 子类能继承 protected 和 default 成员,但能否访问取决于调用上下文:同包子类可直接用;跨包子类只能通过 super.xxx 或 this.xxx,不能访问父类实例的 protected 字段
- public 字段几乎总是错的:破坏封装,失去校验、日志、通知等扩展能力。应改用 private 字段 + public getter/setter
- 重写方法时,子类的访问权限不能比父类更严格(如父类是 protected,子类不能改成 private),但可以更宽松(如改为 public)
- 最小权限原则优先:先写 private,发现需要扩大再逐步调整,而不是一开始就设为 public 等着“以后再收”

















