📜  Java - 带示例的 Lambda 表达式变量捕获(1)

📅  最后修改于: 2023-12-03 15:31:28.047000             🧑  作者: Mango

Java - 带示例的 Lambda 表达式变量捕获

在Lambda表达式中,我们可以通过捕获变量来使用外部的数据。Lambda表达式中可以捕获的变量主要有两种:final变量非final变量

Final变量的捕获

对于final变量,Lambda表达式只能访问该变量,不能修改它的值。下面是一个使用final变量的Lambda表达式示例:

final int x = 5;
Runnable r = () -> {
    System.out.println("x: " + x);
};
r.run();
// Output: x: 5

在上面的示例中,变量x被声明为final,而Lambda表达式中只是访问了x的值,没有修改它的值。这样做是因为Lambda表达式中的变量必须是effectively final的,也就是说,它们在Lambda表达式内部具有final语义。

非Final变量的捕获

对于非final变量,它们在Lambda表达式中也必须具有final语义,即不能在Lambda表达式中修改它们的值。但是,我们可以通过将它们声明为final或者使用实例变量的方式来实现这一点。下面是一个使用非final变量的Lambda表达式示例:

int y = 5;
Runnable r = () -> {
    System.out.println("y: " + y);
};
r.run();
// Output: y: 5

这里的变量y没有被声明为final,但它在Lambda表达式中具有final语义,因为它被用在了Lambda表达式中且没有被修改。如果尝试去修改变量y的值,编译器会抛出一个编译错误。

此外,我们还可以将变量声明为final或者使用实例变量来捕获非final变量。下面是使用实例变量的示例:

public class LambdaVariableCaptureExample {
    private int z = 5;

    public void doSomething(int n) {
        Runnable r = () -> {
            System.out.println("z: " + z);
            System.out.println("n: " + n);
        };
        r.run();
    }
}

LambdaVariableCaptureExample example = new LambdaVariableCaptureExample();
example.doSomething(10);
// Output:
// z: 5
// n: 10

在上面的示例中,我们定义了一个实例变量z,并使用它在Lambda表达式中捕获变量z的值。我们还将参数n作为非final变量传递给了doSomething方法,并在Lambda表达式中捕获它的值。

总结

在Lambda表达式中,我们可以通过捕获变量来使用外部的数据。对于final变量和非final变量,我们都可以在Lambda表达式中捕获它们的值,但是非final变量必须在Lambda表达式中拥有final语义。Lambda表达式可以通过变量捕获读取外部的数据,这使得Lambda表达式在某些情况下比匿名内部类更加灵活和方便。