为什么Kotlin需要在编译后捆绑其运行时?

kan*_*eda 39 kotlin

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

这里的教程为例.

当我做:

kotlinc-jvm hello.kt -include-runtime -d hello.jar
Run Code Online (Sandbox Code Playgroud)

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

Gre*_*pff 37

当您使用Java编写应用程序时,您将依赖所有标准类库.该java.级别(如java.lang.*,java.util.*...)都包含在每一个JRE,这样你就不需要自己包装它们.

Kotlin包含自己的标准类库(Kotlin运行时),与Java类库分开.要分发可以由具有普通旧JRE的任何人运行的jar文件,您还需要捆绑Kotlin运行时.

如果您没有捆绑Kotlin运行时,那么您的用户必须确保在执行应用程序时Kotlin运行时在类路径上.您链接的页面提供了此方案的示例:

编译库

如果您正在开发一个供其他Kotlin应用程序使用的库,则可以生成.jar文件,而不将Kotlin运行时包含在其中.

$ kotlinc-jvm hello.kt -d hello.jar
Run Code Online (Sandbox Code Playgroud)

如果你的目标是其他Kotlin用户,那么可以合理地假设他们已经拥有了Kotlin运行时.但是,如果您尝试为最终用户部署应用程序,则需要包含Kotlin运行时,以便您的应用程序是自包含的.


Ale*_*ers 27

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文件,但这些问题可能是另一个问题.

  • 我还是不明白。JRE(编译的本机代码)+ Kotlin JAR(java 字节码)= 可运行的应用程序?还是还需要 Kotlin Runtime(原生代码)?或者换句话说,“我可以将我的 jar 文件 + kotlin jar 文件交给 Java 7 环境,并期望它能够工作而不必担心底层操作系统吗?” (2认同)

归档时间:

查看次数:

5339 次

最近记录:

6 年,3 月 前