2017-04-14 69 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

很好的答案!謝謝! –