Java子类跨包访问protected成员报错问题咨询
Java protected修饰符访问疑问解答
问题背景
已知Java访问修饰符规则,也查阅了Java官方文档:
protected修饰符指定成员只能在其自身包内访问(与包私有相同),此外,还可以被另一个包中的子类访问。
但实际代码运行出现疑问,项目文件结构如下:
src └── A ├── P1.java └── P2.java
P1.java位于包A中,P2.java与A同级。
P1.java代码:
package A; public class P1 { public int a1; protected int a2; }
P2.java代码:
import A.P1; public class P2 extends P1 { public static void main(String[] args) { P1 p = new P1(); System.out.println(p.a1); System.out.println(p.a2); // 报错? } }
运行时出现错误:
java: a2 has protected access in A.P1
疑问:protected变量应该可以在子类中访问,即使不在同一包中。为何会报错?P2是P1的子类,理应能访问a2。
原因解析
你误解了protected修饰符在跨包子类中的访问范围。官方文档的描述没错,但有个关键细节:跨包的子类只能通过子类自己的实例(或者super关键字)访问父类的protected成员,不能直接通过父类的实例访问。
在你的代码中,P1 p = new P1();创建的是父类的实例,即使在子类P2中,也不能直接通过这个父类实例访问a2。如果要访问a2,可以改成两种方式:
- 使用子类自身的实例:
public class P2 extends P1 { public static void main(String[] args) { P2 p = new P2(); System.out.println(p.a1); System.out.println(p.a2); // 正常访问 } }
- 在子类的非静态方法中使用
super访问(注意main是静态方法,不能用super):
public class P2 extends P1 { public void test() { System.out.println(super.a2); // 正常访问 } public static void main(String[] args) { new P2().test(); } }
简单来说,protected的跨包子类访问权限,是给子类"继承来的成员"用的,而不是让子类随便去操作任意父类实例的protected成员。
内容的提问来源于stack exchange,提问作者maplemaple
相关产品推荐
相关产品推荐

