关于lambda是否为对象的更多信息,请参阅此问题的Lambda FAQ Answer。
考虑到lambda被转换为对象,它们继承(字面上)所有对象的特性。特别地,对象:
equals
,getClass
,hashCode
,notify
,toString
和wait
synchronized
块进行锁定==
和!=
和instanceof
运算符进行比较等等。实际上,所有这些都与lambda的预期用途无关。它们的行为本质上是未定义的。您可以编写使用其中任何一个的程序,并且将获得某些结果,但结果可能会因版本不同而有所不同(甚至在不同的运行中也可能如此!)。
简言之,在Java中,对象具有身份,但值(特别是函数值,如果它们存在的话)不应具有任何身份概念。Java 8没有函数类型。相反,lambda表达式被转换为对象,因此它们具有许多与函数无关的负担,特别是身份。这对我来说似乎不太像“一等公民”。Java 8的lambda表达式符合所有这些标准。因此,它们似乎是一流的。
文章还提到函数名称没有特殊状态,而函数名称只是一个类型为函数类型的变量。Java 8的lambda表达式不符合最后一个标准。Java 8没有函数类型;它有功能接口。这些接口有效地像函数类型一样使用,但它们根本不是函数类型。如果您有一个类型为功能接口的引用,您不知道它是lambda表达式、匿名内部类的实例还是恰好实现该接口的具体类的实例。
总之,Java 8的lambda表达式比我最初想象的更像一流的函数。它们只是不是纯粹的一流函数。
Object o =“Hello”
,则String
文字“Hello”将被转换为类型为Object
的引用。另一方面,“重写”是将简单语法转换为更复杂的语法,你自己也可以编写。转换和重写是不同的概念。 - Stuart Marks<=
与==
比较两个装箱的整数。但总的来说,我最近也在更多地思考这个话题,我会尽快更新我的答案。 - Stuart MarksFunction<String,String> fn = s -> s.toUpperCase();
- Stuart Marks是的,它们是一等值(或者说将会在Java 8发布后成为一等值...)
这意味着您可以将它们作为参数传递,组合它们以创建高阶函数,将它们存储在数据结构中等等。您将能够将它们用于广泛的函数式编程技术。
此外,了解更多关于在这种情况下“一等”意味着什么的定义,请参见:
java.util.functions
包和内部类的语义,使其表现为一等值。对我来说,Java 8中的Lambda只是一种语法糖,因为你不能将其用作第一类公民(http://en.wikipedia.org/wiki/First-class_function),每个函数都应该被包装成对象,这会在与具有纯第一类函数的语言(如SCALA)进行比较时带来许多限制。Java 8闭包只能捕获不可变(“有效最终”)的非本地变量。
这里有更好的解释,为什么它是语法糖 Java Lambdas and Closures