Подтвердить что ты не робот

Что такое захваченные переменные в Java Local Classes

Документация Java для Local Classes говорит, что:

Кроме того, локальный класс имеет доступ к локальным переменным. Однако локальный класс может обращаться только к локальным переменным, объявленным окончательным. Когда локальный класс обращается к локальной переменной или параметру охватывающий блок, он захватывает эту переменную или параметр. Например, конструктор PhoneNumber может получить доступ к локальной переменной numberLength потому что он объявлен окончательным; numberLength - захваченная переменная.

Что такое захваченная переменная, каково ее использование и зачем это нужно? Пожалуйста, помогите мне понять концепцию этого.

4b9b3361

Ответ 1

Что такое захваченная переменная, каково ее использование и зачем это нужно?

Захваченная переменная - это копия, которая может быть использована во вложенном классе. Причина, по которой он должен быть скопирован, заключается в том, что объект не может жить в текущем контексте. Он должен быть final (или эффективно final в Java 8), поэтому нет путаницы в том, будут ли видны изменения в переменной (потому что они не будут)

Примечание: Groovy имеет это правило, и изменение локальной переменной может означать изменение значения в классе-оболочке, что особенно сбивает с толку, если задействовано несколько потоков.

Пример переменной захвата.

public void writeToDataBase(final Object toWrite) {
    executor.submit(new Runnable() {
        public void run() {
             writeToDBNow(toWrite);
        }
    });
    // if toWrite were mutable and you changed it now, what would happen !?
}
// after the method returns toWrite no longer exists for the this thread...

Ответ 2

Захваченная переменная - одна из сторонности вашего локального класса, объявленная в окружающем блоке. На некоторых языках это называется закрытием .

В примере из Oracle Docs (упрощенный) переменная numberLength, объявленная вне класса PhoneNumber, "захвачена".

final int numberLength = 10;  // in JDK7 and earlier must be final...

class PhoneNumber {
   // you can refer to numberLength here...  it has been "captured"
}

Ответ 3

Вот сообщение, описывающее это: http://www.devcodenote.com/2015/04/variable-capture-in-java.html

Вот фрагмент сообщения:

"Навязывается Java как мандат, что если внутренний класс, определенный внутри метода, ссылается на локальную переменную этого метода, эта локальная переменная должна быть определена как окончательная."

Это связано с тем, что функция может завершить выполнение и удалить из стека процессов со всеми уничтоженными переменными, но может быть, что объекты внутреннего класса все еще находятся в куче, ссылаясь на конкретную локальную переменную этой функции. Чтобы противостоять этому, Java создает копию локальной переменной и дает это как ссылку на внутренний класс. Чтобы поддерживать согласованность между двумя копиями, локальная переменная должна быть "окончательной" и не изменяемой.