Java 8 是否支持闭包?

2022-08-31 21:00:28

我很困惑。我以为Java 8将从石器时代出现并开始支持lambdas/闭包。但是当我尝试这个时:

public static void main(String[] args) {
    int number = 5;

    ObjectCallback callback = () -> {
        return (number = number + 1);
    };

    Object result = callback.Callback();
    System.out.println(result);
}

...它说.呃,我认为这不是一个结束。这听起来就像是按值而不是按引用复制环境。number should be effectively final

奖金问题!

Android 会支持 Java 8 的功能吗?


答案 1

为什么哦,为什么,Java。为什么哦,为什么。

您需要与相关的Oracle Java团队成员进行长时间(私人)讨论,以获得真正的答案。(如果他们愿意和你说话...)


但我怀疑这是向后兼容性和项目资源限制的结合。事实上,从务实的角度来看,目前的方法“足够好”。

将过程上下文实现为一类对象(即闭包)需要某些局部变量的生存期扩展到声明方法调用的返回之后。这意味着您不能只是将它们放在堆栈上。相反,您最终会遇到这样一种情况,即某些局部变量必须是堆对象的字段。这意味着您需要对JVM架构进行一种新的隐藏类或根本性更改。

虽然从技术上讲可以实现这种东西,但Java语言不是“绿地”语言。在Java中支持“真正的闭包”所需的性质的改变将是困难的:

  • Oracle和第三方实现者需要付出巨大的努力来更新所有工具链。(我们不只是在谈论编译器。有调试器,探查器,混淆器,字节码工程框架,持久性框架...

  • 然后,存在这样的风险,即其中一些更改可能会影响数百万个现有部署的Java应用程序的向后兼容性。

  • 对以某种方式利用JVM的其他语言等有潜在的影响。例如,Android依赖于JVM架构/字节码文件作为其Davlik工具链的“输入语言”。有Python,Ruby和代码为JVM平台生成的各种函数式语言的语言实现。


简而言之,Java中的“真正闭包”对于所有相关人员来说都是一个非常可怕的命题。“决赛结束”黑客是一种务实的妥协,确实有效,这在实践中已经足够好了。

最后,在将来的版本中始终有可能删除该限制。(我不会屏住呼吸....)final


Android 会支持 Java-8 功能吗?

除非有人有可靠的内部知识,否则这是不可能回答的。如果他们这样做了,他们会疯狂地在这里透露它。当然,谷歌还没有宣布支持Java 8。

但好消息是,KitKat和相应版本的Android Studio或Eclipse ADT现在支持Java 7语法扩展。


答案 2

你必须陈述你对“关闭”的定义。

对我来说,“闭包”是某种东西(函数或对象或其他可以以某种方式运行的东西,比如拥有方法),它从其封闭的作用域中捕获(“关闭”)局部变量,并且可以在其代码中使用该变量,即使函数或对象的方法在以后运行, 包括当封闭范围不再存在时。在不同的语言中,可以通过值和/或引用来捕获变量。

根据这个定义,Java匿名类(自Java 1.1以来一直存在)闭包,因为它们可以从其封闭范围引用局部变量。

Java 8 中的 Lambda 基本上是匿名类的一个特例(即,一个匿名类,它仅使用一个方法实现一个接口(“函数接口”),并且没有实例变量,并且不引用自身(显式或隐式使用))。任何 lambda 都可以重写为等效的匿名类表达式。因此,上面所说的也适用于lambdas。this

呃,我认为这不是一个结束。

好吧,先生,你对“关闭”的定义很混乱。