默认访问权限(package-private)仅对同一包内所有类可见,无论继承关系;跨包类即使继承也无法访问,编译报错“cannot find symbol”,且default类不可被其他包import。

Java 中默认访问权限(也叫包私有、package-private)不写任何修饰符,它的可见性完全由包结构决定——只对同一包内的所有类开放,无论是否有继承关系,也不管是否是静态或实例成员。
包私有控制可见性的核心规则
它不是靠“谁调用”来判断,而是看“代码写在哪个包里”:
- 同包中的任意类(包括普通类、子类、工具类、测试类)都能直接访问 default 成员,无需继承,也无需 getter
- 跨包的类,哪怕继承了该类,也完全看不到 default 字段或方法;编译直接报错 “cannot find symbol”
- default 类本身不能被其他包 import,哪怕它内部有 public 方法也没用——因为类都加载不了
- 包私有对 static 和非 static 成员一视同仁,区别只在于调用方式(如 MyClass.defaultStaticField 或 obj.defaultInstanceField)
典型使用场景和设计意图
它不是“退而求其次”的选择,而是有意为之的封装策略:
- 适合包内协作组件:比如 DTO 构建器、JSON 解析辅助类、数据库连接池工具类,对外不暴露,但包内多个类需要共享逻辑
- 避免污染公共 API:把内部状态或过渡方法设为 default,既方便调试和单元测试(同包测试类可直接验证),又不构成对外契约
- 比 private 更灵活,比 protected 更安全——不向子类“让渡”权限,也不向同包非子类“过度开放”
常见误区与注意事项
容易混淆的地方,其实都源于没抓住“包”这个唯一边界:
- 子类即使继承了 default 成员,也无法在子类中使用——不是“继承失败”,而是根本不可见,就像那行代码不存在
- 同包内非子类可以调用 default 方法,但不能重写它(重写要求方法已存在且可访问,而 default 方法对子类不可见)
- 模块系统(JDK 9+)下,即使在同一个命名模块中,跨包的 default 成员依然不可见;模块导出(exports)只影响 public 类,不影响 default 成员的包级限制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











