Java四种访问修饰符严格定义“在什么位置能访问”,关键看类、包、继承关系:public全局可见(需import且类可加载),protected允同包类及跨包子类访问但权限不同,default仅限本包,private仅本类(含内部类特例)。

Java 的四种访问修饰符不是简单规定“谁可以调用”,而是严格定义“在什么位置能访问”——关键看三点:当前代码所处的类、是否同包、是否为子类。
public:全局可见,但依赖类可加载
任何包、任何类都能访问 public 成员,前提是目标类本身能被正确加载。这需要满足两个条件:
- 目标类必须是 public 类,且文件名与类名完全一致
- 调用方需通过 import 或全限定名引用该类,否则编译报错 “cannot find symbol”
- 接口中的方法默认就是 public,显式声明属于冗余
- 子类重写 public 方法时,访问修饰符不能降级(比如不能改成 protected)
protected:子类 + 同包,但访问方式不同
protected 允许两类场景访问,但权限不对等:
- 同包内任意类:可通过对象实例调用(如 obj.protectedMethod()),但不能继承、不能重写、也不能用 super 访问
- 跨包子类:可通过自身实例或 super 调用父类 protected 成员,但不能通过父类实例调用(如 parent.protectedMethod() 编译失败)
- 注意:protected 不等于“只给子类用”,同包非子类也能访问,只是不能继承
默认(无修饰符):纯包内可见,不随继承传递
这是真正的“包私有”,只对当前 package 生效,和继承无关:
- 同包所有类均可访问,无论是否有继承关系
- 跨包子类即使继承了该类,也无法访问其 default 成员
- default 类本身不能被其他包 import,哪怕它内部有 public 方法也不行
- 适合封装包内协作逻辑,比如 DTO 构建器、解析工具等
private:本类封闭,内部类是例外
private 成员仅在声明它的最外层类内部可访问:
- 连直接子类都不可见,无法继承、重写或调用
- 同一类的不同实例之间可以互相访问对方的 private 成员
- static 或非 static 内部类可自由访问外围类的 private 成员(语言特例)
- JDK 9+ 模块系统下,反射默认禁止访问 private 成员,需显式加 --add-opens 参数
访问修饰符只控制编译期可见性,运行时不受限制。反射、序列化、模块系统都可能重新定义“可见”的边界。

















