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

Java中通过对象访问protected成员的权限疑问

解开Java Protected成员访问的困惑

嘿,我之前也踩过这个protected权限的坑,太懂你这种“明明规则说子类和同包能访问,怎么用对象调用就报错”的疑惑了!其实问题出在大家对protected的规则理解不够细致——它不是简单的“子类/同包就能随便访问”,还要看你访问的方式和被访问对象的实际类型。

先给你拆解清楚核心规则:

  • 同包场景:不管是不是子类,同包内的任何类都能直接访问该包内类的protected成员,包括通过对象调用,这个是没问题的。
  • 子类场景:这里分两种情况,很容易踩坑:
    1. 如果是子类自己的实例(比如用this或者直接调用继承来的成员),完全可以访问,这是继承带来的权限。
    2. 如果是父类的对象(哪怕你用子类引用指向它),或者是子类对象但在子类外部的代码中访问,这时候就会受限——除非子类和父类在同一个包。

结合你的包结构(根包javaapplication1下有entities和newpackage两个子包),我给你举具体代码例子,一看就明白:

示例代码

父类(在javaapplication1.entities包)

package javaapplication1.entities;

public class Parent {
    protected String protectedField = "我是protected成员";
}

子类(在javaapplication1.newpackage包)

package javaapplication1.newpackage;

import javaapplication1.entities.Parent;

public class Child extends Parent {
    public void testAccess() {
        // 1. 访问自身继承的protected成员:正常运行
        System.out.println(this.protectedField);
        
        // 2. 创建父类对象并访问其protected成员:编译报错!
        Parent parentObj = new Parent();
        // System.out.println(parentObj.protectedField); // 这行会报错
        
        // 3. 创建子类对象并访问其protected成员:正常运行
        Child childObj = new Child();
        System.out.println(childObj.protectedField);
    }
}

同包的普通类(在javaapplication1.entities包)

package javaapplication1.entities;

import javaapplication1.newpackage.Child;

public class SamePackageClass {
    public void testAccess() {
        // 访问父类对象的protected成员:正常(同包)
        Parent parentObj = new Parent();
        System.out.println(parentObj.protectedField);
        
        // 访问子类对象的protected成员:正常(同包)
        Child childObj = new Child();
        System.out.println(childObj.protectedField);
    }
}

不同包的非子类(在javaapplication1.newpackage包)

package javaapplication1.newpackage;

import javaapplication1.entities.Parent;

public class NonChildClass {
    public void testAccess() {
        // 访问父类对象的protected成员:报错(不同包且非子类)
        Parent parentObj = new Parent();
        // System.out.println(parentObj.protectedField);
        
        // 访问子类对象的protected成员:报错(不同包且非子类)
        Child childObj = new Child();
        // System.out.println(childObj.protectedField);
    }
}

总结一下关键逻辑

protected权限的核心是:看「访问代码所在的类」和「被访问对象所属的类」之间的关系,而不是只看访问类是不是子类:

  1. 若访问类和被访问对象的类同包:无限制,随便访问。
  2. 若访问类是被访问对象的类的子类:
    • 只能访问自身实例或子类实例的protected成员(因为这些成员是子类继承来的);
    • 不能直接访问父类实例的protected成员(除非同包)。

这样是不是就清楚为什么你用对象调用会出现异常情况了?本质是没搞清楚protected权限的上下文限制~

内容的提问来源于stack exchange,提问作者Jtx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:26:23