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

时间:2014-02-25 20:15:24

标签: java

Local Classes的Java文档说:

  

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

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

3 个答案:

答案 0 :(得分:16)

  

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

捕获的变量是已复制的变量,因此可以在嵌套类中使用。它必须被复制的原因是对象可能在当前上下文中存活。它必须是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...

答案 1 :(得分:2)

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

the 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"
}

答案 2 :(得分:2)

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

以下是该帖子的摘录:

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

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