在 Java 中,"闭包" 这个概念通常与 lambda 表达式和匿名类相关联。虽然 Java 并不直接使用 "闭包" 这个术语,但它通过 lambda 表达式和匿名类实现了类似于闭包的功能。
什么是闭包?
闭包是一个函数或代码块,它能够捕获并访问其作用域之外的变量。在某些编程语言中,闭包可以用来创建函数对象,这些对象可以访问定义它们的环境中的变量,即使这些变量在闭包创建时已经超出了它们的作用域。
Java 中的闭包特性
Java 8 引入了 lambda 表达式,这使得 Java 可以更接近于实现闭包的概念。以下是 Java 中与闭包相关的特性:
- Lambda 表达式:可以捕获和使用其外部作用域中的变量。
- 匿名类:在 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 详解