java成员类(内部类)如何访问外部类的实例变量?
我写了下面的代码,这些代码运行良好,但我对合成方法有一个疑问。因为这些都是为了访问私有数据而生成的。但是我有一个在成员类中使用的外部类的公共实例变量,所以为了访问实例变量,它创建了合成方法(就像在类文件中一样!!)
代码片段如下:
public class TestInnerClass {
public int x = 10;
public static void main(String[] args) {
TestInnerClass test= new TestInnerClass();
A obj = test.new A();
obj.display();
}
class A {
void display() {
System.out.println(x);
}
}
}
类文件生成如下。 对于内部A类测试类$A:
import java.io.PrintStream;
class TestInnerClass$A {
TestInnerClass$A(TestInnerClass paramTestInnerClass) {
}
void display() {
System.out.println(this.this$0.x);
}
}
为TestInReclass生成类文件:
import java.io.PrintStream;
public class TestInnerClass {
public int x = 10;
public static void main(String[] args) {
TestInnerClass test = new TestInnerClass();
TestInnerClass tmp13_12 = test; tmp13_12.getClass(); A obj = new A();
obj.display();
}
class A {
A() {
}
void display() {
System.out.println(TestInnerClass.this.x);
}
}
}
因此,我的疑问是:
(一)。为什么显示方法在类文件中有不同的定义
(二)。为什么TestInnerClass类中的文件实例变量被访问为TestInnerClass。这x。但是TestInnerClass$A的类文件中的相同代码与此不同。这是0美元。x
3)为什么JVM将合成方法创建为这个$0,而实例变量是公共的
# 1 楼答案
您可以从外部类访问变量,因为它们位于内部类的闭包中Closures在Java中存在,但在Java字节码中不存在该概念。您看到的合成变量和访问器是使闭包在java字节码中工作所需的混乱的一部分
完全公开:Java中的闭包实际上不是闭包。实际闭包捕获创建函数的整个环境。在Java中,内部类始终可以访问创建它的方法的外部类成员和最终局部变量。然而,它不能像在JavaScript这样的语言中那样访问非最终局部变量
# 2 楼答案
我不完全确定我是否理解您的问题,但我将尝试回答他们:
您不能将java文件与类似的类文件进行比较。某些特征只存在于一个世界中。内部类就是这样一个特性。它们没有直接翻译成字节码。一些代码按摩是必要的,这就是您在这里发现的
因为在编译内部类时,对外部类(
TestInnerClass.this
)的隐式引用会转换为显式引用。由于此引用不能具有标识符this
,因此称为this$0
这不是一种方法,据我所知,它不是公开的。它是一个存储对封闭类的对象的引用的字段。需要它才能访问该对象的
x