我觉得除了此处找到的文档之外还没有完全解释这一点,因此我将根据我最近的理解尝试更详细地介绍。
我已将ShadowClass
外部类的名称NestedClasses
更改为并将变量从 type 更改int
为 type String
。
这是在第一个嵌套类中添加第二个嵌套类的示例,以显示如何NestedClasses.this.x
在更深层的类中继续表现。
public class NestedClasses {
public String x = "outer class variable";
class FirstLevel {
public String x = "first level class variable";
void methodInFirstLevel(String x) {
System.out.println("methodInFirstLevel:");
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("NestedClasses.this.x = " + NestedClasses.this.x);
}
class SecondLevel {
public String x = "second level class variable";
void methodInSecondLevel(String x) {
System.out.println("methodInSecondLevel:");
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("NestedClasses.this.x = " + NestedClasses.this.x);
System.out.println("FirstLevel.this.x = " + FirstLevel.this.x);
System.out.println("NestedClasses.FirstLevel.this.x = " + NestedClasses.FirstLevel.this.x);
}
}
}
public static void main(String[] args) {
NestedClasses st = new NestedClasses();
NestedClasses.FirstLevel fl = st.new FirstLevel();
NestedClasses.FirstLevel.SecondLevel sl = fl.new SecondLevel();
fl.methodInFirstLevel("first level method arg");
System.out.println();
sl.methodInSecondLevel("second level method arg");
}
}
输出:
methodInFirstLevel:
x
= 一级方法 arg
this.x
= 一级类变量
NestedClasses.this.x
= 外部类变量
methodInSecondLevel:
x
= 二级方法 arg
this.x
= 二级类变量
NestedClasses.this.x
= 外部类变量
FirstLevel.this.x
= 一级类变量
NestedClasses.FirstLevel.this.x
= 一级类变量
三个实例化对象(st
, fl
, sl
)中的每一个都包含一个指向堆中不同内存空间x
的指针,可以在其中找到 的值。我相信编译器正在向最外层“向后”搜索以找到第一个匹配的类,因为它看到的this
是嵌套类中的类名前缀。它找到的第一个匹配类是它在确定需要搜索哪个对象实例化时将引用的类x
。这意味着NestedClasses.FirstLevel.this.x
实际上是向后退两步,向前一步来确定要查看堆中的哪个内存空间,即引用哪个内存空间x
。
总结:
NestedClasses.this.x
- 前缀的类名
NestedClasses
告诉 JVM 正在使用哪个类,这个类必须在当前范围内是可访问的。
- 该
this
关键字告诉 JVM 查看被引用类的实例化对象的内存空间,而不是类对象本身的内存空间(用于类的静态成员)。更具体地说,this
将引用用于(并且需要)实例化非静态内部类的外部类的实例化。
x
附加到的对象成员this
告诉 JVM 在它正在查看的内存空间中搜索什么。