变量作用域
我们首先来看一个栗子:
public static void repeatMessage(String text, int delay) {
ActionListener listener = event -> {
System.out.println(text);
Toolkit.getDefaultToolkit().beep();
};
new Timer(delay, listener).start();
}
如果我们现在去调用这个方法:
repeatMessage("Hello", 1000);
现在我们回过头去看看那个lambda表达式中的变量text。注意这个变量并不是在这个lambda表达式中定义的。实际上,这时 repeatMessage 方法的一个参数变量。
这里似乎有些问题,因为lambda表达式的代码可能会在 repeatMessage 调用返回很久以后才运行,而那时这个参数变量已经不存在了。如何保留text变量呢?
我们首先来回顾一下lambda表达式中有哪几个部分:
- 一个代码块
- 参数
- 自由变量的值,这里是指非参数而且不在代码中定义的变量。
在我们的例子中,lambda表达式有一个自由变量text。表示lambda表达式的数据结构必须存储自由变量的值,在这里就是字符串 “Hello” 。我们说它被lambda表达式捕获。
这里需要注意,在Java中,要确保所捕获的值是明确定义的,这里有一个重要的限制。在lambda表达式中,只能引用值不会改变的变量。下面是一个错误的示例:
public static void count(int start,