30

Java 8 的闭包真的是一流的价值,还是只是一种语法糖?

4

5 回答 5

60

我会说 Java 8 闭包(“Lambdas”)既不是语法糖,也不是一流的值。

我在回答另一个 StackExchange 问题时已经解决了语法糖的问题。

至于 lambdas 是否是“头等舱”,这真的取决于你的定义,但我会证明 lambdas 并不是真正的头等舱。

从某种意义上说,lambda 想要成为一个函数,但 Java 8 并没有添加函数类型。而是将 lambda 表达式转换为函数式接口的实例。这允许将 lambdas 添加到 Java 8 中,只需对 Java 的类型系统进行少量更改。转换后,结果是一个引用,就像任何其他引用类型一样。事实上,使用 Lambda ——例如,在一个传递了 lambda 表达式作为参数的方法中——与通过接口调用方法没有区别。接收函数接口类型参数的方法无法判断它是否传递了 lambda 表达式或恰好实现该函数接口的某个类的实例。

有关 lambda 是否为对象的更多信息,请参阅此问题的Lambda 常见问题解答

鉴于 lambda 被转换为对象,它们继承(字面上)对象的所有特征。特别是对象:

  • 有各种方法,如equals, getClass, hashCode, notify, toString, 和wait
  • 有一个身份哈希码
  • 可以被synchronized块锁定
  • 可以使用==and!=instanceof运算符进行比较

等等。事实上,所有这些都与lambda 的预期用途无关。他们的行为本质上是不确定的。您可以编写一个使用其中任何一个的程序,您会得到一些结果,但结果可能因版本而异(甚至运行运行!)。

更简洁地重申这一点,在 Java 中,对象具有标识,但值(特别是函数值,如果它们存在的话)不应该有任何标识的概念。Java 8 没有函数类型。相反,lambda 表达式被转换为对象,因此它们有很多与函数无关的包袱,尤其是身份。对我来说,这似乎不是“头等舱”。

2013-10-24 更新

自从几个月前发布我的答案以来,我一直在进一步思考这个话题。从技术角度来看,我上面写的一切都是正确的。结论可能更准确地表示为 Java 8 lambdas 不是值(与first-class相对),因为它们携带了大量对象包袱。然而,仅仅因为它们不纯并不意味着它们不是一流的。考虑一等函数的维基百科定义。简而言之,那里列出的考虑一流功能的标准是以下能力:

  • 将函数作为参数传递给其他函数
  • 从其他函数返回函数
  • 将函数分配给变量
  • 在数据结构中存储函数
  • 让函数匿名

Java 8 lambda 满足所有这些标准。所以这确实让他们看起来是一流的。

文章还提到了没有特殊地位的函数名称,而是函数名称只是一个变量,其类型是函数类型。Java 8 lambda 不满足最后一个标准。Java 8 没有函数类型;它具有功能接口。这些可以像函数类型一样有效地使用,但它们根本不是函数类型。如果您有一个类型为函数式接口的引用,您不知道它是 lambda、匿名内部类的实例,还是碰巧实现该接口的具体类的实例。

总而言之,Java 8 的 lambda 比我最初想象的更具有一流的功能。它们只是不是纯粹的一流功能。

于 2013-03-06T07:27:40.710 回答
6

的,它们是一流的值(或者将是,一旦 Java 8 发布......)

从某种意义上说,您可以将它们作为参数传递,将它们组合成高阶函数,将它们存储在数据结构中等。您将能够将它们用于广泛的函数式编程技术。

有关“头等舱”在此上下文中的含义的更多定义,另请参见:

于 2013-03-05T10:43:41.387 回答
2

正如我所看到的,它是语法糖,但除了类型推断、java.util.functions内部类的新包和语义之外,它确实显示为一等值。

于 2013-03-05T10:45:57.430 回答
1

将变量绑定到外部上下文的真正闭包有一些开销。我会认为 Java 8 的实现是最优的,足够纯净。

至少它不仅仅是语法糖。

而且我不知道任何更优化的实现。

于 2013-03-05T10:52:40.157 回答
0

对我来说,Java 8 中的 Lambdas 只是语法糖,因为你不能将它用作 First class Citizen ( http://en.wikipedia.org/wiki/First-class_function ) 每个函数都应该包装到对象中,与它相比它施加了很多限制具有纯一流功能的语言,如 SCALA。Java 8 闭包只能捕获不可变(“实际上是最终的”)非局部变量。

这里有更好的解释为什么它是语法糖Java Lambdas 和 Closures

于 2014-09-23T11:02:49.983 回答