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

Java继承中super.name可访问父类私有字段的原因及疑问

Java继承中私有字段访问的疑问解答

作为Java新手,在做继承演示时遇到了一个困惑:当尝试用name或this.name访问父类的私有字段name时,编译器报错,这符合“子类无法访问父类私有字段”的说法;但使用super.name时却能正常编译运行,调用相关方法后还能更新对应的name值。

使用环境:IDEA + JDK 18

完整演示代码

public class IV_extend_class_ver2 {
    public static class Person {
        //field
        private String name = "Person";

        //default Constructor

        //method
        public String getName(){   return this.name;   }
        public void setName(String name){   this.name = name;   }
    }

    //Worker extends from Person
    public static class  Worker extends Person {
        private int salary;

        public int getSalary() {   return this.salary; }
        public void setSalary(int salary) {   this.salary = salary;   }

        //access the private member in superclass
        public String hello() {
            return "Hello, " + super.name;
            // If write name or this.name,  an error would get in IDEA
            // But if I wirte super.name,it compiles successfully
            // and if I call hello() in next part, it works 
        }
    }

    public static void main(String[] args) {
        Worker man = new Worker();
        System.out.println(man.hello());
        man.setName("Bob");
        System.out.println(man.hello());
    }
}

运行结果

Hello, Person
Hello, Bob

疑问1:为何super.name可以正常运行,而name或this.name会报错?

  • Java中私有字段的访问权限是类级别的,严格限定在定义该字段的类内部,子类本身不能直接访问父类的私有字段。
  • 你遇到的super.name能编译通过,是因为父类Person和子类Worker都属于同一个顶级类IV_extend_class_ver2的静态内部类。在这种情况下,JDK的访问检查会放宽——同一个顶级类下的嵌套类之间,允许通过super关键字访问彼此的私有成员。
  • 直接写name或this.name时,编译器会先在子类自身作用域查找name字段,找不到后尝试向上查找父类字段,但父类name是私有,不符合访问规则,因此报错;而super.name明确指定要访问父类成员,在同顶级类的场景下,这个访问被JVM允许。

疑问2:为何修改的是子类对象的name字段,而非super指代的父类?

  • 首先纠正误解:子类对象没有独立的name字段,name是父类的私有字段。当子类继承父类时,父类的所有字段会被包含在子类对象的内存空间中,不存在“父类对象”和“子类对象”分离的情况——一个Worker对象就是一个完整的对象,里面包含了Person的字段和Worker自己的字段。
  • super关键字只是指代当前对象中的父类部分,而不是一个独立的父类对象。调用man.setName("Bob")时,setName是父类的方法,它修改的是man这个子类对象中属于父类部分的name字段。之后调用hello()时,super.name读取的就是这个被修改后的字段值,所以看起来像是“子类对象的name”,本质是子类对象中包含的父类私有字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:33:15