2017-04-14 66 views
1

我想了解在Java中被捕获的变量的概念。在Java中存储捕获的变量在哪里?

我发现很详细的文章吧:http://www.devcodenote.com/2015/04/variable-capture-in-java.html

,我不知道字节码部分:

同样,访问一个封闭的方法,该变量的隐藏的副本的局部变量被制作并保存在内部类文件中,从中访问该变量。

如何将它保存到类文件(在编译期间),在编译时可能不知道最终的原始值?

例如:

void foo(int x){ 
    final int y = 10 + x; 

    class LocalClass(){ 
     LocalClass(){ 
      System.out.println(y); // works fine 
     } 
    } 
} 

如果作者是错误的,是局部变量复制到LocalClass在方法区的运行空间?

+0

我觉得你过于复杂的事情。此外,绝大多数在方法中声明的类都是匿名类,它们可以用于非常特定和狭义的目的。 – efekctive

+1

必须将* value *在运行时复制到内部类的每个* instance *中。复制和存储变量的代码可以在编译时创建。 –

回答

3

作者似乎指的是捕获的变量被翻译成本地/匿名类的字段的事实。

如果disasemble 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 
    } 
} 
+1

很好的答案!谢谢! –