Java 闭包

137 阅读2分钟

在 Java 中,"闭包" 这个概念通常与 lambda 表达式和匿名类相关联。虽然 Java 并不直接使用 "闭包" 这个术语,但它通过 lambda 表达式和匿名类实现了类似于闭包的功能。

什么是闭包?

闭包是一个函数或代码块,它能够捕获并访问其作用域之外的变量。在某些编程语言中,闭包可以用来创建函数对象,这些对象可以访问定义它们的环境中的变量,即使这些变量在闭包创建时已经超出了它们的作用域。

Java 中的闭包特性

Java 8 引入了 lambda 表达式,这使得 Java 可以更接近于实现闭包的概念。以下是 Java 中与闭包相关的特性:

  1. Lambda 表达式:可以捕获和使用其外部作用域中的变量。
  2. 匿名类:在 Java 8 之前,匿名类是实现类似闭包行为的主要方式。

Lambda 表达式示例

import java.util.function.Function;

public class ClosureExample {
    public static void main(String[] args) {
        int num = 10;
        Function<Integer, Integer> adder = (x) -> x + num;

        // 使用 lambda 表达式
        System.out.println(adder.apply(5)); // 输出: 15
    }
}

在这个示例中,lambda 表达式 (x) -> x + num 捕获了外部作用域中的变量 num

注意事项

  • 变量的有效性:被 lambda 表达式或匿名类捕获的外部变量必须是“最终有效”的(effectively final)。这意味着在 lambda 表达式创建之后,不能修改这些变量的值。(如果是对象内部属性还是会被修改的-此种方式不规范)
  • 不可变性:由于捕获的变量必须是有效最终的,因此它们在 lambda 表达式中是不可变的,这与某些其他支持闭包的语言不同。

匿名类示例

在 Java 8 之前,匿名类是实现类似闭包行为的主要方式:

public class ClosureExample {
    public static void main(String[] args) {
        final int num = 10;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(num);
            }
        };

        runnable.run(); // 输出: 10
    }
}

在这个示例中,匿名类捕获了外部作用域中的变量 num

总结

虽然 Java 没有显式地使用“闭包”这个术语,但通过 lambda 表达式和匿名类,Java 实现了类似于闭包的功能。这些特性允许函数或代码块捕获并使用其外部作用域中的变量,提供了一种强大的方式来处理函数式编程和事件驱动编程。

下一篇可以看下
java 柯里化
java8 Lambda 详解