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

2022-09-01 21:09:06

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

考虑到 Scala 闭包比为 Java 8 规划的闭包强大得多,我想知道是否有可能调用一个 Java 方法,从 Scala 中获取一个闭包,在 Java 中定义一个闭包并将其交给 Scala 函数等?

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


答案 1

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

由于最新的Project Lambda提案是将函数类型全部消除,并且只是为实现具有单个astract方法(SAM类型)的接口创建某种花哨的推理,因此我预见到以下内容:

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

    Java 泛型的复杂性(特别是如何在泛型接口中表达//或 //)也可能使事情复杂化。IntintIntegerUnitNothingvoid

  • 使用 Scala 函数来实现 Java SAM 与现在没有什么不同 - 您需要为要实现的特定接口创建转换。implicit

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

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

对我来说更有趣的是虚拟扩展方法的建议,这些方法将允许Java Collections API使用lambdas。根据这些的实现方式,它们可能会大大简化我们在更改Scala代码时必须处理的一些二进制兼容性问题,并且它们可能有助于更容易和更有效地实现特征。

我希望一些 Scala 开发人员参与进来并提供他们的意见,但我实际上还没有在 Project Lambda 列表中看到任何关于 Scala 的讨论,也没有任何参与者跳出来把我当作 Scala 开发人员。


答案 2

无论隐式转换是否开箱即用,您都可以非常轻松地做到这点。collection.JavaConversions

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