You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,可以改成两种方式:

  1. 使用子类自身的实例:
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); // 正常访问
    }
}
  1. 在子类的非静态方法中使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:21:08