为什么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。*
因此,看来:
-
“Kotlin运行时”实际上只是一个“Kotlin类库” (而不是像JRE那样严格的单独的“运行时”);
-
当Kotlin代码被编译成Java字节码时,Kotlin不见了,但替换它的字节码需要访问Kotlin类库 ; 所以
-
Kotlin运行时必须可用于原始Kotlin代码的任何Java字节代码 ,这可以通过将Kotlin运行时与这些代码捆绑在一起来完成。
对我来说,Kotlin团队使用“运行时”这个词引起了很多混淆。 我更喜欢他们称之为“Kotlin支持类”,而不是用一个非常不同的内涵的Java术语。
这并不能解释为什么需要kotlin
包名称空间下的很多东西,或者Kotlin文件是否可以编写,实际上完全不依赖于Kotlin运行时,但这可能是另一个问题。