包访问权限是隔离组件内部非公开实现的天然屏障,因其将可见性与物理包组织绑定,同包类可自由调用,跨包类编译期不可见且反射受限,比private灵活、比protected安全,支持API包与实现包的清晰分工。

包访问权限(默认)之所以是隔离组件内部非公开实现的天然屏障,关键在于它把“可见性”和“物理组织”绑定在了一起——只有同包内的类才能看到、调用这些成员,而包本身是代码可部署、可管理的最小逻辑单元。
包访问权限天然支持模块边界
Java 的包不是单纯目录结构,而是语义化的封装单位。当你把一组协作紧密的类(比如 OrderService、OrderValidator、OrderRepositoryImpl)放在 com.example.order 包里,并让 OrderValidator 的校验逻辑方法使用默认修饰符:
class OrderValidator {
boolean isValid(Order order) { ... } // 没有 public/protected/private
}这个方法对外部包(如 com.example.payment)完全不可见,哪怕对方 import 了该类也无法调用。这种限制不靠文档约定,也不靠运行时检查,而是编译期强制生效。
- 同包类可以自由调用,协作高效;
- 跨包类无法绕过,连反射都拿不到(JDK 9+ 模块系统下更严格);
- 不需要额外抽象或接口包装,零成本实现“内部可用、外部不可见”。
它比 private 更灵活,比 protected 更安全
-
private锁死在单个类内,不适合跨类协作; -
protected允许子类访问,但子类可能散落在任意包中,破坏封装意图; -
default则明确划出一个“协作圈”:只要不在这个包里,就不是设计预期的协作者。
这使得团队能自然形成「API 包 + 实现包」分工。例如:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
com.example.api:只放public interface OrderService; -
com.example.internal:放DefaultOrderService、SqlOrderRepository等,默认访问成员; - 外部模块只能依赖
api包,根本看不到internal包里的具体类(尤其在模块化项目中,若未exports com.example.internal,连编译都通不过)。
配合工厂模式进一步加固
当必须对外提供实例时,常用静态工厂方法返回接口,而工厂本身与实现类同包:
// 在 com.example.internal 包中
public interface OrderService { ... }
class DefaultOrderService implements OrderService { ... }
public class Services {
public static OrderService createOrderService() {
return new DefaultOrderService(); // 可以 new,因为同包
}
}调用方只拿到接口,无法 new 实现类,也无法访问其默认方法——既开放能力,又守住实现细节。
不复杂但容易忽略。

















