protected 在 Java 中控制继承可见性:允许子类(含跨包)访问,拒绝同包非子类直接访问;同一包内仅子类可访问,不同包仅子类可访问,非子类不可访问。
protected 在 java 中不是“保护”属性不被访问,而是**控制继承可见性**:它允许子类(即使跨包)访问父类的成员,同时拒绝同包内非子类的直接访问。理解这一点,是正确使用它的前提。
protected 的实际作用范围
一个 protected 成员在以下情况可被访问:
- 同一类内部 —— 当然可以
- 同一包内的其他类 —— 仅限于该类是当前类的子类时;否则不可访问(这点常被误解)
- 不同包中的子类 —— ✅ 允许访问(这是跨包继承的核心支持)
- 不同包中的非子类 —— ❌ 不允许访问(哪怕通过对象引用也不行)
跨包继承中正确声明与访问 protected 成员
假设你有如下结构:
package com.example.base;
public class Animal {
protected String name; // ✅ 跨包子类可访问
protected void breathe() { // ✅ 同样可被重写或调用
System.out.println(name + " is breathing");
}
}
package com.example.sub;
import com.example.base.Animal;
public class Dog extends Animal { // 跨包继承
public void introduce() {
System.out.println("I'm " + name); // ✅ 可直接访问父类 protected 字段
breathe(); // ✅ 可直接调用父类 protected 方法
}
}
注意:不能在 com.example.sub 包中新建一个非 Dog 子类的类(比如 Helper),然后试图通过 new Animal().name 访问 —— 编译会失败。
为什么不能靠 protected “隐藏核心逻辑”?
很多人误以为 protected 能防止外部窥探,其实它只是放宽了继承访问权限。若想真正封装核心数据:
立即学习“Java免费学习笔记(深入)”;
- 把字段设为 private,提供受控的 protected getter/setter(可被子类调用,但无法绕过逻辑)
- 将关键行为设计为 final protected 方法,允许子类使用但禁止重写
- 敏感操作建议用 private + final 配合策略模式或模板方法,把可变部分留给子类实现(用 abstract protected)
常见误区与规避方式
- 误:protected 字段 = 安全的共享状态 → 实际上子类可任意修改,可能破坏父类不变量。建议优先用 private + protected 访问器
- 误:同一包下任意类都能访问 protected 成员 → 错!必须是继承关系,否则编译报错
-
误:protected 方法能被跨包子类通过父类引用来调用 → 不行!必须是子类实例自身调用(如
this.breathe()),不能写new Animal().breathe()


















