被Java和Scala互操作所迷惑



我对Scala和Java的交互方式有点困惑。例如,我正在构建一个使用 Scala 2.11.6 版的 Play 应用程序,我需要一个对象来表示日期。

理想情况下,我想使用Java 8中的LocalDate,但是如果Scala 2.11针对Java JDK 6,这可能吗?

我想更好地了解不同版本的Java如何与Scala一起工作,以及两者之间的关系。

为了回答你的具体问题,如果你用JDK8运行scalac,那么是的,你可以在Scala 2.11中使用LocalDate

至于更普遍的问题,Scala和Java有四种基本的交互方式,它们在版本上是相互分离的(至少在理论上是这样)。

  • 在编译时,必须运行某个版本的java scalac
  • 在编译时,scalac读取某个版本的 JVM 字节码
  • 在编译时,scalac发出某个版本的 JVM 字节码
  • 在运行时,java(通过scala脚本)运行发出的 JVM 字节码scalac

因此,让我们看看这如何叠加Scala 2.10.5的scalac,Scala 2.11.x的scalac,以及即将推出的Scala 2.12.x的scalac和Java 6,7和8。

  • 斯卡拉 2.10.5:
    • scalac可以由Java 6,7或8运行(由于java的向后兼容性)
    • scalac可以读取 Java 6 或 7 字节码
    • scalac发出Java 6(默认)或7(可选)字节码用于
    • Scala特定的部分,但如果它读取Java 7字节码(例如,因为你使用的是Java 7库),那么你的最终产品中也将包含Java 7字节码,由Java 6字节码调用。
    • 根据您在上一步中的行为,您将拥有纯 Java 6 字节码,然后可以由 Java 6、7 或 8 的java运行,
    • 或者具有 Java 7 特定功能的字节码,然后只能由 Java 7 或 8 的java运行。
  • Scala 2.11.x:
    • scalac可以由 Java 6、7 或 8 运行
    • scalac可以读取 Java 6、7 或 8 字节码(取决于 2.11.x 的版本 x 可以读取和使用或多或少的 Java 8 字节码功能)
    • scalac发出 Java 6(默认)或 Java 7(可选)字节码
    • 这里的故事与 2.10.5 相同
  • Scala 2.12.x:
    • scalac只能由 Java 8 运行
    • scalac可以读取Java 8字节码和7字节码,凭借Java的向后兼容性
    • (我不确定这里的故事scalac是否做出了任何额外的努力来比Java 8的java向后兼容,例如Java 6兼容性)
    • scalac发出 Java 8 字节码
    • Java 8 的java必须用于运行生成的二进制文件

只是为了强调理论上这些步骤是完全解耦的,Scala 2.12 的scalac可以假设由 Scala 2.11 的scalac编译,以产生一个可以由 Java 6 运行的scalac,但其结果输出只能由 Java 8 java 运行。

在 Scala 2.11 的情况下,您可以使用 Java 8,只要您向 scalac 提供这些类即可。LocalDate的唯一特别之处在于它与 Java 平台捆绑在一起,因此如果您在使用 Java 8 中运行scalac,则无法访问它,而如果您在使用 Java 6 或 7 运行scalac则无法访问它。如果您使用的是第三方 Java 8 库,则可以将编译后的 JAR 提供给 Scala 2.11.x scalac,以便使用,无论哪个 Java 版本正在运行scalac。不过,该字节码可能会进入您自己的发出的 JAR 中,这可能会使下游用户的事情复杂化。

这意味着对于任何非纯 Scala 项目,您必须让您的消费者知道您用于生成的任何 JAR 的 Scala 版本和 Java 版本。如果你的项目是一个库,并且你的消费者使用兼容的 Scala 版本但不兼容的 Java 版本,她/他的代码可以编译,但不会运行。

Scala版本和Java版本

是不同的:你可以在不同的Java版本(例如1.6,1.7,1.8)上运行相同的Scala版本(比如2.10.5)。

但是,如果您使用特定于 JVM 版本的 JSE 类型,则您的 Scala 代码将无法与以前的 Java 版本一起运行。就好像你用provided依赖项构建你的 Scala app/lib,而运行时没有实际提供它。

此外,如果根据配置的Java版本scalac生成的字节码比JRE(用Java 8编译但使用JRE 1.6执行)的字节码更新,则不能将其解释为任何纯Java代码。

最新更新