Scala闭包与Java 8闭包之间的兼容性

时间:2010-06-15 15:02:46

标签: java scala closures scala-java-interop

在阅读了一些OpenJDK邮件列表条目后,似乎Oracle开发人员目前正在进一步从关闭提案中删除内容,因为早期的Java语言设计错误使得Java闭包的引入变得复杂。

考虑到Scala闭包比Java 8计划的闭包要强大得多,我想知道是否有可能e。 G。调用Java方法从Scala中获取闭包,在Java中定义一个闭包并将其赋予Scala函数等。

Java闭包会像字节码中的Scala对应物一样表示还是不同? 是否可以缩小Java / Scala闭包之间的功能差距?

3 个答案:

答案 0 :(得分:15)

我认为这比假设这里有两组利益相关者更复杂。 Project Lambda人似乎主要独立于Oracle人员occasionally throwing something over the wall,而项目Lambda人员间接地发现这些人。{3}}。 (Scala,当然是第三个利益相关者。)

由于latest Project Lambda proposal是一起消除函数类型,只是为实现具有单一astract方法( SAM 类型)的接口创建某种奇特的推理,我预见到以下内容:

  • 调用需要Scala闭包的Scala代码完全取决于Function*特征的实现(以及一般特征的实现) - 它是否在Java编译器中显示为SAM(它是在Scala-land中)还是非抽象方法对JVM也是抽象的。 (我认为他们目前看起来像是抽象的,因为traits是作为接口实现的,但我对Scala的实现几乎一无所知。这可能是互操作性的一大障碍。)

    Java泛型的并发症(特别是如何表达Int / int / IntegerUnit / Nothing / void通用接口)也可能使事情复杂化。

  • 使用Scala函数实现Java SAM与现在没有任何区别 - 您需要为要实现的特定接口创建implicit转换。

如果JVM获得了函数类型(并且Oracle似乎没有消除这种可能性),那么它可能取决于它是如何实现的。如果它们是实现特定接口的第一类对象,那么Scala需要兼容的是make Function*实现新接口。如果在JVM中完全实现了一种新类型,那么这可能很困难 - Scala开发人员可能会像使用Array那样使用魔术来包装它们,或者它们可能会创建create implicit转换。 (一种新的语言概念似乎有点牵强。)

我希望所有这些讨论的结果之一是各种JVM语言的所有都会以某种标准方式来表示闭包 - 所以Scala,Groovy,JRuby等等......所有人都能以最小的麻烦来回关闭。

对我来说更有意思的是virtual extension methods的提议,它允许Java Collections API使用lambdas。根据这些实现的方式,它们可能会大大简化我们在更改Scala代码时必须处理的一些二进制兼容性问题,并且它们可能有助于更轻松有效地实现特征。

我希望一些Scala开发人员能够参与并提供他们的意见,但我实际上没有在项目Lambda列表上看到任何关于Scala的讨论,也没有任何参与者作为Scala开发人员跳出来。< / p>

答案 1 :(得分:7)

使用隐式转化 a la collection.JavaConversions,无论是否开箱即用,您都可以非常轻松地完成此任务。

当然,这显然不是,因为可能是Java闭包变成了JVM 在运行时生成的类型 - 我好像回想一下Neal Gafter的演讲,并按照这些方式说了些什么

答案 2 :(得分:2)

注意:5年后,SCALA 2.12.0-M3 (Oct. 2015)确实包含了此增强功能:

  

Scala 2.12以与Java 8 相同的方式发出闭包。

     

对于每个lambda,编译器生成一个包含lambda体的方法   在运行时,此方法作为参数传递给JDK提供的LambdaMetaFactory,从而创建一个闭包对象。

     

与Scala 2.11相比,新方案的优势在于编译器不再为每个lambda生成匿名类。这导致了更小的JAR文件。