Java 8 lambda 表达式和一等值 [英] Java 8 lambda expression and first-class values

查看:14
本文介绍了Java 8 lambda 表达式和一等值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Are Java 8 closures really first-class values or are they only a syntactic sugar?

推荐答案

我想说的是 Java 8 闭包(Lambdas")不仅是语法糖,也不是一流的值.

I would say that Java 8 closures ("Lambdas") are neither mere syntactic sugar nor are they first-class values.

我在另一个 StackExchange 问题的回答中解决了语法糖问题.

I've addressed the issue of syntactic sugar in an answer to another StackExchange question.

至于 lambdas 是否是一流的",这实际上取决于您的定义,但我会说明 lambdas 并不是真正的一流.

As for whether lambdas are "first class" it really depends on your definition, but I'll make a case that lambdas aren't really first class.

从某种意义上说,lambda 想成为一个函数,但 Java 8 没有添加函数类型.相反,一个 lambda 表达式被转换成一个函数式接口的实例.这使得 lambdas 可以添加到 Java 8 中,只需对 Java 的类型系统进行微小的更改.转换后的结果是一个引用,就像任何其他引用类型一样.事实上,使用 Lambda —— 例如,在一个将 lambda 表达式作为参数传递的方法中 —— 与通过接口调用方法没有区别.接收函数接口类型参数的方法无法判断它是传递了 lambda 表达式还是某个碰巧实现该函数接口的类的实例.

In some sense a lambda wants to be a function, but Java 8 is not adding function types. Instead, a lambda expression is converted into an instance of a functional interface. This has allowed lambdas to be added to Java 8 with only minor changes to Java's type system. After conversion, the result is a reference just like that of any other reference type. In fact, using a Lambda -- for example, in a method that was passed a lambda expression as parameter -- is indistinguishable from calling a method through an interface. A method that receives a parameter of a functional interface type can't tell whether it was passed a lambda expression or an instance of some class that happens to implement that functional interface.

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

For more information about whether lambdas are objects, see the Lambda FAQ Answer to this question.

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

Given that lambdas are converted into objects, they inherit (literally) all the characteristics of objects. In particular, objects:

  • 有各种方法,如equalsgetClasshashCodenotifytoString> 和 wait
  • 有一个身份哈希码
  • 可以被synchronized块锁定
  • 可以使用 ==!=instanceof 运算符进行比较
  • have various methods like equals, getClass, hashCode, notify, toString, and wait
  • have an identity hash code
  • can be locked by a synchronized block
  • can be compared using the == and != and instanceof operators

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

and so forth. In fact, all of these are irrelevant to the intended usage of lambdas. Their behavior is essentially undefined. You can write a program that uses any of these, and you will get some result, but the result may differ from release to release (or even run to run!).

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

Restating this more concisely, in Java, objects have identity, but values (particularly function values, if they were to exist) should not have any notion of identity. Java 8 does not have function types. Instead, lambda expressions are converted to objects, so they have a lot baggage that's irrelevant to functions, particularly identity. That doesn't seem like "first class" to me.

更新 2013-10-24

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

I've been thinking further on this topic since having posted my answer several months ago. From a technical standpoint everything I wrote above is correct. The conclusion is probably expressed more precisely as Java 8 lambdas not being pure (as opposed to first-class) values, because they carry a lot of object baggage along. However, just because they're impure doesn't mean they aren't first-class. Consider the Wikipedia definition of first-class function. Briefly, the criteria listed there for considering functions first-class are the abilities to:

  • 将函数作为参数传递给其他函数
  • 从其他函数返回函数
  • 将函数赋值给变量
  • 在数据结构中存储函数
  • 函数是匿名的

Java 8 lambdas 满足所有这些条件.所以这确实让他们看起来一流.

Java 8 lambdas meet all of these criteria. So that does make them seem first-class.

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

The article also mentions function names not having special status, instead a function's name is simply a variable whose type is a function type. Java 8 lambdas do not meet this last criterion. Java 8 doesn't have function types; it has functional interfaces. These are used effectively like function types, but they aren't function types at all. If you have a reference whose type is a functional interface, you have no idea whether it's a lambda, an instance of an anonymous inner class, or an instance of a concrete class that happens to implement that interface.

总而言之,Java 8 lambdas 是比我原先想象的更一流的函数.它们只是不是一流的功能.

In summary, Java 8 lambdas are more first-class functions than I had originally thought. They just aren't pure first-class functions.

这篇关于Java 8 lambda 表达式和一等值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆