Что такое захваченные переменные в Java Local Classes
Документация Java для Local Classes говорит, что:
Кроме того, локальный класс имеет доступ к локальным переменным. Однако локальный класс может обращаться только к локальным переменным, объявленным окончательным. Когда локальный класс обращается к локальной переменной или параметру охватывающий блок, он захватывает эту переменную или параметр. Например, конструктор PhoneNumber может получить доступ к локальной переменной numberLength потому что он объявлен окончательным; numberLength - захваченная переменная.
Что такое захваченная переменная, каково ее использование и зачем это нужно? Пожалуйста, помогите мне понять концепцию этого.
Ответы
Ответ 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 создает копию локальной переменной и дает это как ссылку на внутренний класс. Чтобы поддерживать согласованность между двумя копиями, локальная переменная должна быть "окончательной" и не изменяемой.