为什么Java Lambda也称为Closures

时间:2015-03-17 13:34:17

标签: java java-8

我目前正在浏览Java Lambda并发现它也称为Closures。

请问它是否也称为闭包?我想要一个技术解释。

3 个答案:

答案 0 :(得分:16)

这是两个不同的术语,经常在同一个背景下被提及。

  • lambda 基本上只是一个匿名函数。示例:() -> System.out.println("Hello")。这是一个功能,但它没有名称。

  • 关闭是关于范围界定的术语。例如,当你引用lambda中的局部变量时,如下所示

    int localInt = 17;
    
    saveThisFunction(() -> System.out.println(localInt));
    

    在lambda中创建捕获 localInt的闭包。在文本上看起来很明显可以在lambda中访问localInt,但请记住,lambda可以在从堆栈中弹出localInt后很长时间存储和调用。

因此,创建lambda表达式通常需要创建一个闭包(隐式)。

答案 1 :(得分:2)

从技术上讲,它是错误的,lambda表达式和闭包是两个略有不同的东西。

Lambdas 是匿名函数,在Java世界中采用匿名单个方法类的形式(另请参阅functional interfaces):

Runnable r1 = () -> System.out.println("I'm Runnable");

闭包是lambda表达式的特定子类型,其中局部变量已绑定到特定封闭环境中定义的变量。

在Java世界中,您只是在here编写类似于此示例的内容:

final int x = 99;

Consumer<Integer> myConsumer = (y) -> 
{
    System.out.println("x = " + x);
    System.out.println("y = " + y);
};

有关闭包的更完整的抽象定义:

  

在操作上,闭包是一个将函数与环境一起存储的数据结构:一个映射,它将函数的每个自由变量(本地使用的变量,但在封闭范围中定义)与创建闭包时名称绑定的值或存储位置。

     

闭包 - 与普通函数不同 - 允许函数通过闭包对它们的引用来访问那些捕获的变量,即使在函数范围之外调用函数

Source

最后一部分意味着你可以这样做:

public class Funct{


    public static Consumer<Integer> getThatClosure(){
        final int x = 99;

        Consumer<Integer> myConsumer = (y) -> 
        {
            System.out.println("x = " + x);
            System.out.println("y = " + y);
        };
        return myConsumer;
    }

    public static void main(String... args){
        Consumer<Integer> cons=getThatClosure();
        cons.accept(0);
    }

} 

使用此输出:

x=99
y=0

答案 2 :(得分:-1)

仅仅因为这些术语是等价的(我认为和“匿名函数”一样),这就是在不同语言中调用类似机制的方式,例如: Groovy有闭包

顺便说一下,我不认为这是问这些问题的正确答案