package-private(不写修饰符)是明确设计的包级访问边界,适用于同包协作但不对外暴露的场景,如TokenReader类或isValidInput()方法,同包可见、跨包不可见。

封装使用 package-private 权限,核心是“不写任何修饰符”,让成员仅在同一个包内可见——它不是被忽略的默认值,而是有明确设计意图的访问边界。
什么时候该用 package-private 而不是 private?
当某个字段、方法或类需要被同包下的其他类协作使用,但又不希望暴露给外部包(包括子类)时,就该用 package-private。
- 比如解析器模块中,
TokenReader只被本包的JsonParser和XmlParser调用,那就声明为class TokenReader { ... }或void readNext() { ... } - 工具类的内部逻辑方法(如字符串预处理、校验辅助)若只供本包调用,设为 package-private 比 public 更安全,比 private 更实用
- 测试友好:JUnit 测试类通常和被测类放在同一包下,把待测的中间状态或关键方法设为 package-private,测试可直接访问,无需反射或 mock
怎么正确声明 package-private 成员?
不加任何访问修饰符即可,编译器自动识别为包级私有。注意它适用于类、字段、方法、构造方法,但不能用于接口中的方法(接口方法默认 public)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 类:
class InternalCache { ... }→ 只能在com.example.cache包内被 new 或继承 - 字段:
String cacheKey;→ 同包类可直接读写,跨包不可见 - 方法:
boolean isValidInput(String s) { ... }→ 同包其他类可调用,外部包调用会编译报错 - 构造方法:
Logger(String name) { ... }→ 同包内可 new,外部包无法实例化(除非提供 public 静态工厂)
常见误用与避坑点
package-private 看似简单,但容易因理解偏差导致封装失控或调用失败。
立即学习“Java免费学习笔记(深入)”;
- 误以为“不写就是 private”:实际是更宽松的包级可见,同包任意类都能访问,不是安全隔离
- 跨包继承时误信能访问父类 package-private 成员:即使子类继承了父类,只要不在同一包,就不能调用其默认权限的方法或字段
- 模块化项目(Java 9+)中,即使同包但不同 module,也需在
module-info.java中显式exports才能被其他模块访问 - IDE 常把 package-private 成员标为“package-private”灰字,这不是警告,而是提示——别把它当成缺陷去改
和 public/private 的配合使用建议
一个健壮的包内结构,往往三者协同:private 封装细节,package-private 支撑协作,public 定义对外契约。
- 字段一律优先 private,通过 package-private 的 getter/setter 或 builder 方法供同包调用
- public 类里可含 package-private 方法,作为“半开放接口”,供本包扩展而不承诺长期兼容
- 避免把本该 private 的逻辑放开成 package-private “图省事”;也别把本该包内共享的工具方法硬塞进 public 接口里

















