Java Local Classes中捕获的变量是什么

Local Classes的Java文档说:

此外,本地类可以访问局部变量。 但是,本地类只能访问声明为final的局部变量。 当本地类访问封闭块的局部变量或参数时,它会捕获该变量或参数。 例如,PhoneNumber构造函数可以访问局部变量numberLength,因为它被声明为final; numberLength是捕获的变量。

什么是捕获变量,它的用途是什么以及为什么需要它? 请帮助我理解它的概念。

什么是捕获变量,它的用途是什么以及为什么需要它?

捕获的变量是已复制的变量,因此可以在嵌套类中使用。 它必须被复制的原因是对象可能超出当前上下文。 它必须是final (或者在Java 8中有效final ),因此不会混淆是否会看到对变量的更改(因为它们不会)

注意: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... 

捕获的变量是来自本地类外部的变量 – 一个在周围块中声明。 在某些语言中,这称为闭包。

在Oracle Docs (简化)的示例中, 类PhoneNumber 之外声明的变量numberLength被“捕获”。

 final int numberLength = 10; // in JDK7 and earlier must be final... class PhoneNumber { // you can refer to numberLength here... it has been "captured" } 

这是一篇描述它的post: http : //www.devcodenote.com/2015/04/variable-capture-in-java.html

这是post的一个片段:

“Java强制要求如果方法中定义的内部类引用该方法的局部变量,那么该局部变量应该被定义为final。”

这是因为该函数可能完成执行并从进程堆栈中删除,所有变量都被销毁,但可能是内部类的对象仍然在堆上引用该函数的特定局部变量。 为了解决这个问题,Java制作了局部变量的副本,并将其作为对内部类的引用。 为了保持2个副本之间的一致性,本地变量被强制为“最终”且不可修改。