被Java和Scala互操作混淆

时间:2016-02-25 23:21:11

标签: java scala

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

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

我希望更好地了解不同版本的Java如何与Scala协同工作以及两者如何相关。

2 个答案:

答案 0 :(得分:3)

要回答您的具体问题,如果您使用JDK8运行scalac,那么您可以将LocalDate与Scala 2.11一起使用。

至于更一般的问题,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& #39; s scalac和Java 6,7和8。

  • Scala 2.10.5:
    • scalac可以由Java 6,7或8运行(由于java的向后兼容性)
    • scalac可以读取Java 6或7字节码
    • scalac为Scala特定部分发出Java 6(默认)或7(可选)字节码,但如果它读取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
    • 运行 由于Java的向后兼容性,
    • scalac可以读取Java 8字节码和7字节码(我不确定scalac是否需要做任何额外工作比Java 8 java更向后兼容,例如Java 6兼容性)
    • scalac发出Java 8字节码
    • 必须使用Java 8' java来运行生成的二进制文件

只是为了强调理论上这些步骤是完全分离的,Scala 2.12的scalac可以假设由Scala 2.11 scalac编译,导致scalac 1}}可以由Java 6运行,但其结果输出只能由Java 8 java运行。

对于Scala 2.11,只要将这些类提供给scalac,就可以使用Java 8。关于LocalDate的唯一特殊之处在于它与Java平台捆绑在一起,因此如果您使用Java 8运行scalac,则隐式地可以访问它,如果您运行{{1}则不要这样做使用Java 6或7。如果您使用的是第三方Java 8库,则可以将已编译的JAR提供给Scala 2.11.x scalac以供使用,无论哪个Java版本正在运行scalac 。该字节码可能会进入您自己发出的JAR,这可能会使下游用户感到困惑。

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

答案 1 :(得分:0)

Scala版本和Java版本截然不同:您可以在不同的Java版本(例如1.6,1.7,1.8)上运行相同的Scala版本(比如说2.10.5)。

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

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