Где хранится захваченная переменная в 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 в области методов во время выполнения?

1 ответ

Решение

Автор, кажется, ссылается на тот факт, что захваченные переменные переводятся в поля локального / анонимного класса.

Если вы дезассемблируете 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
    }
}
Другие вопросы по тегам