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
相关产品推荐
相关产品推荐

