为什么Kotlin编译后需要捆绑它的运行时?

我只是想了解底层架构,我认为我错了。

以这里的教程为例。

当我做:

kotlinc-jvm hello.kt -include-runtime -d hello.jar 

如果编译器已经将代码转换为Java字节码,为什么需要将Kotlin运行时绑定到jar中?

当你用Java编写应用程序时,你可以依赖所有的标准类库。 java. 每个JRE都包含类(例如java.lang.*java.util.* …),所以您不需要自己打包。

Kotlin包含自己的标准类库( Kotlin运行时 ),与Java类库分开。 要发布任何人都可以使用普通的旧JRE运行的jar文件,还需要绑定Kotlin运行时。

如果您没有绑定Kotlin运行时,那么您的用户在执行应用程序时必须确保Kotlin运行时在类路径上。 您链接的页面给出了这种情况的一个例子:

编译一个库

如果您正在开发要由其他Kotlin应用程序使用的库,则可以在不包括Kotlin运行时的情况下生成.jar文件。

 $ kotlinc-jvm hello.kt -d hello.jar 

如果您针对其他Kotlin用户,则可以合理地假设他们已经拥有Kotlin运行时。 但是,如果您尝试为最终用户部署应用程序,那么您希望包含Kotlin运行时,以便您的应用程序是自包含的。

Greg Kopff接受的答案解释了需要捆绑某些东西的一般情况,但是我觉得这个问题的主要观点被忽略了: 为什么要编译成Java字节码 (因此不再是Kotlin) 需要Kotlin“运行时“?

我的期望(我怀疑这个提问者)是一旦编译完成,就再也没有Kotlin的痕迹,所以不需要Kotlin运行时。

我的期望是,“运行时”是某种本地二进制文件,如JRE,直接负责执行字节码。

不过,从包装上的Kotlin语言参考资料来看:

许多软件包默认导入到每个Kotlin文件中:

  • 科特林。*
  • kotlin.annotation。*
  • kotlin.collections。*
  • kotlin.comparisons。*(自1.1)
  • kotlin.io。*
  • kotlin.ranges。*
  • kotlin.sequences。*
  • kotlin.text。*

因此,看来:

  1. “Kotlin运行时”实际上只是一个“Kotlin类库” (而不是像JRE那样严格的单独的“运行时”);

  2. 当Kotlin代码被编译成Java字节码时,Kotlin不见了,但替换它的字节码需要访问Kotlin类库 ; 所以

  3. Kotlin运行时必须可用于原始Kotlin代码的任何Java字节代码 ,这可以通过将Kotlin运行时与这些代码捆绑在一起来完成。

对我来说,Kotlin团队使用“运行时”这个词引起了很多混淆。 我更喜欢他们称之为“Kotlin支持类”,而不是用一个非常不同的内涵的Java术语。

这并不能解释为什么需要kotlin包名称空间下的很多东西,或者Kotlin文件是否可以编写,实际上完全不依赖于Kotlin运行时,但这可能是另一个问题。