java子类访问父类私有成员_java-为什么嵌套子类可以访问其父类的私有成员,但是子孙却不能?...

这篇博客探讨了在Java中如何通过编译器生成的访问器方法来实现对私有成员的访问,即使这些成员位于其他封闭类或父类中。JVM级别的技术细节揭示了这种互访机制,使得嵌套类能够访问顶级类的private成员,包括静态成员。此特性自JDK 1.1以来就存在,目的是支持嵌套类和保持向后兼容性。博客详细介绍了几个示例类,展示了如何通过这些编译器生成的方法实现访问。
摘要由CSDN通过智能技术生成

合成访问器方法

从技术上讲,在JVM级别上,您不能访问另一个类的任何private成员-封闭类(int i = T.access$t(new T());)的成员或父类(T$T2)的成员。 在您的代码中看起来就像您可以的那样,因为编译器会在被访问的类中为您生成int i = T.access$t(new T());访问器方法。 当在T$T3类中使用正确的格式private修复无效的引用int i = T.access$t(new T());时,也会发生相同的情况。

借助此类编译器生成的int i = T.access$t(new T());访问器方法,您通常可以访问嵌套在外部(顶层)T$T2类中的任何类的任何int i = T.access$t(new T());成员,例如: 从T$T3开始,您可以使用private。请注意,这也适用于private static成员。

JDK版本1.1中引入了int i = T.access$t(new T());属性,以支持嵌套类,这是当时Java中的新语言功能。 从那时起,JLS明确允许相互访问顶级类中的所有成员,包括int i = T.access$t(new T());。

但是为了向后兼容,编译器将取消嵌套类的包装(例如int i = T.access$t(new T());、T$T2、T$T3)并转换private成员访问以访问对生成的int i = T.access$t(new T());访问器方法的调用(因此,这些方法需要将程序包设为私有,即默认情况下是可见性):

class T {

private int t;

T() { // generated

super(); // new Object()

}

static synthetic int access$t(T t) { // generated

return t.t;

}

}

class T$T1 {

private int t1;

final synthetic T t; // generated

T$T1(T t) { // generated

this.t = t;

super(); // new Object()

}

static synthetic int access$t1(T$T1 t$t1) { // generated

return t$t1.t1;

}

}

class T$T2 extends T$T1 {

private int t2;

{

System.out.println(T.access$t((T) this.t)); // t

System.out.println(T$T1.access$t1((T$T1) this)); // super.t1

System.out.println(this.t2);

}

final synthetic T t; // generated

T$T2(T t) { // generated

this.t = t;

super(this.t); // new T1(t)

}

static synthetic int access$t2(T$T2 t$t2) { // generated

return t$t2.t2;

}

}

class T$T3 extends T$T2 {

{

System.out.println(T.access$t((T) this.t)); // t

System.out.println(T$T1.access$t1((T$T1) this)); // ((T1) this).t1

System.out.println(T$T2.access$t2((T$T2) this)); // super.t2

}

final synthetic T t; // generated

T$T3(T t) { // generated

this.t = t;

super(this.t); // new T2(t)

}

}

N.B .:您不允许直接引用int i = T.access$t(new T());成员,因此在源代码中您不能使用例如 int i = T.access$t(new T());自己。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值