合成访问器方法
从技术上讲,在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());自己。