我试图理解Java中捕获变量的概念。
我发现了相当详细的文章:http://www.devcodenote.com/2015/04/variable-capture-in-java.html
我不确定字节码部分:
类似地,为了访问封闭方法的局部变量,变量的隐藏副本被创建并保存在内部类 file 中,从中访问变量。
如果在编译时可能不知道最终原始值,如何将其保存到类文件中(在编译期间)?
例如:
void foo(int x){
final int y = 10 + x;
class LocalClass(){
LocalClass(){
System.out.println(y); // works fine
}
}
}
如果作者错了,局部变量是否在运行时复制到方法区域的LocalClass空间?
答案 0 :(得分:3)
作者似乎指的是捕获的变量被翻译成本地/匿名类的字段这一事实。
如果您使用LocalClass
,您可以看到这一点(其中Main
是封闭类的名称):
class Main$1LocalClass {
final int val$y;
final Main this$0;
Main$1LocalClass();
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LMain;
5: aload_0
6: iload_2
7: putfield #2 // Field val$y:I
10: aload_0
11: invokespecial #3 // Method java/lang/Object."<init>":()V
14: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
17: aload_0
18: getfield #2 // Field val$y:I
21: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
24: return
}
第一个字段是局部变量y
,第二个字段是对封闭实例的引用。此外,这些值隐式地传递给本地类的构造函数。
基本上LocalClass
看起来像这样:
class LocalClass {
final int val$y;
final Main this$0;
LocalClass(Main arg1, int arg2) {
this.this$0 = arg1; // bytecode 1-2
this.val$y = arg2; // bytecode 5-7
super(); // bytecode 10-11
System.out.println(this.val$y); // bytecode 14-21
}
}