public最无约束,跨包调用但破坏封装;protected限子类及同包,跨包子类不可调用父类成员;默认权限为包级私有,非private;private仅本类可见,内部类除外;均为编译期契约。

public 能被任何地方访问,但滥用会破坏封装
只要类、方法或字段声明为 public,就允许跨包、跨类、甚至跨模块调用。这不是“最开放”而是“最无约束”——它不检查调用者是否属于合理使用范围。
- 常见错误现象:
public字段直接暴露内部状态,导致外部随意修改,后续加校验或监听逻辑时被迫重构 - 使用场景:API 接口方法、工具类的静态工厂方法(如
Objects.requireNonNull())、公开的常量(public static final) - 性能/兼容性影响:无运行时开销,但一旦发布,删除或降级
public成员会直接破坏二进制兼容性
protected 允许子类和同包访问,但子类不能跨包调用父类 protected 成员
protected 的关键不是“保护”,而是“继承可见性”。它比 public 收紧,又比默认权限宽松,但容易误解为“子类 anywhere 都能用”。
- 常见错误现象:在包 A 定义
protected void doWork(),然后在包 B 的子类里尝试通过父类实例调用parent.doWork()—— 编译报错:error: doWork() has protected access in Parent - 使用场景:模板方法模式中的钩子方法(
protected void beforeProcess())、需要被继承重写但不希望被外部随意调用的方法 - 参数差异:Java 16+ 对
protected构造器有额外限制,跨包子类无法调用父类protected构造器,除非显式super()在同一包内
默认(包级私有)是真正意义上的“模块内可见”,不是“没写就是 private”
不写任何修饰符 ≠ 私有,而是“仅限当前 package”。这是 Java 最常被低估也最实用的权限级别,适合隐藏实现细节但保留测试友好性。
- 常见错误现象:把工具类方法设为
private,结果单元测试(在同包下)无法调用,只好改成public,污染 API - 使用场景:包内协作的辅助方法(如
parseConfigString())、DTO 内部构建逻辑、测试可访问但不应被外部依赖的接口实现 - 兼容性影响:包名变更即断开访问,比
public更脆弱;但比private更灵活,无需反射就能被同包测试覆盖
private 只对本类有效,连子类都不可见,但内部类是个例外
private 是唯一真正“锁死”的权限,连继承关系都穿透不了。但它对内部类网开一面:一个类的 private 成员,可以被其定义的 static 或非 static 内部类直接访问。
立即学习“Java免费学习笔记(深入)”;
- 常见错误现象:以为
private方法能被子类重写——根本不会编译,JVM 甚至不把它当“可继承成员”处理 - 使用场景:纯实现细节(如
private Node findRoot())、避免被误用的构造逻辑、内部状态校验辅助函数 - 性能影响:JIT 可能对
private方法做更激进的内联,但实际差异微乎其微;重点在于语义清晰——它说“这里不提供契约,只服务当前类”
权限修饰符不是安全机制,也不控制运行时行为。它们纯粹是编译期契约,且 private 和 protected 的边界比直觉中更硬——尤其跨包继承和内部类访问这两处,稍不注意就会卡在编译阶段。










