这是第一次使用闭包示例,但是我很难控制范围。
public class TestLambdaClosure {
public static void main(String[] args) {
int a= 10;
int b=20;
//doProcess(a, i-> System.out.println(i+b));
doProcess(a, new Process() {
@Override
public void process(int i) {
System.out.println(i+b);
}
});
}
public static void doProcess(int i, Process p) {
p.process(i);
}
interface Process{
void process(int i);
}
}
调用p.process(i)时,“ b”如何进入范围?另外,控制流程在内部如何工作?
答案 0 :(得分:2)
闭包使您可以访问其外部作用域中的变量。在这种情况下,外部作用域变量(b)被声明为现在有效地称为final的Java社区,这意味着自初始化(int b = 20)以使其易于访问。
请记住,变量必须声明为final或有效地为final,才能使其作为闭包起作用。
现在,关于您的代码,此代码声明了 doProcess(...)方法,该方法返回用于部分执行 doProcess(...)方法的方法。
process(...)方法访问 doProcess(...)方法外部范围中的 b 。声明为有效的最终结果。
答案 1 :(得分:2)
关闭:您可以通过将代码和上下文封装到单个结构中来对行为进行建模。
关键概念是您的功能代码(lambda)不仅可以引用其自己的变量,还可以引用对于代码可见的所有外部变量,在您的情况下为变量/**
* Get array key from position
*/
function get_array_key($arr, $pos = 0)
{
foreach ($arr as $key => $value) {
$mykey[] = $key;
}
if (isset($mykey[$pos])) return $mykey[$pos];
}
和a
。 / p>
在Java中,闭包只能引用final或有效的final变量。这意味着,变量的引用不能更改,并且闭包只能看到实际的不可变状态(该值实际上不是不可变的,最终意味着不能重新分配变量)。从理论上讲,这不是必需的。例如,在JavaScript中,您可以编写以下代码:
b
在这里,function newCounter() {
let count = 0;
return function() { return ++count; };
}
const nc = newCounter();
console.log(nc()); // 1
console.log(nc()); // 2
console.log(nc()); // 3
的内部功能仍然可以访问newCounter
(其上下文)并可以对其进行修改(变量是可变的)。
请注意,变量count
在闭包之外的代码的任何其他部分都无法访问。