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

soc*_*soc 24 java closures scala scala-java-interop

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

考虑到Scala闭包比Java 8计划的闭包更强大,我想知道是否可以调用Java方法从Scala中获取闭包,在Java中定义闭包并将其赋予Scala函数等?

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

Ken*_*oom 15

我认为这比假设这里有两组利益相关者更复杂.在Lambda项目的人似乎大多独立于甲骨文的人的工作,偶尔扔东西在墙上的Lambda项目人们发现间接.(Scala,当然是第三个利益相关者.)

由于最新的Project Lambda提议是一起消除函数类型,并且只是为实现具有单个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需要做的兼容就是Function*实现新接口.如果在JVM中完全实现了一种新类型,那么这可能很困难 - Scala开发人员可能会像现在为Arrays 一样使用魔术包装它们,或者它们可能会创建创建implicit转换.(一种新的语言概念似乎有点牵强.)

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

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

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

  • @soc:那就是说,我对Lambda项目明显缺乏与其他JVM选区的讨论感到不安. (4认同)

oxb*_*kes 7

你很可能是能够做到这一点非常容易地使用隐式转换 一拉 collection.JavaConversions他们是否来开箱.

当然,这显然不是这样,因为可能是Java闭包被转换为JVM 在运行时生成的类型- 我似乎记得Neal Gafter的演示文稿在这些行中说了些什么


Von*_*onC 2

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

Scala 2.12 发出与 Java 8 相同风格的闭包

对于每个 lambda,编译器都会生成一个包含 lambda 主体的方法。
在运行时,此方法作为参数传递给LambdaMetaFactoryJDK 提供的方法,后者创建一个闭包对象。

与 Scala 2.11 相比,新方案的优点是编译器不再为每个 lambda 生成匿名类。这会导致 JAR 文件明显更小。