JVM上的Kotlin-它如何提供这么多功能?
介绍
Java虚拟机
快速简单的定义: Java虚拟机 由计算机用来运行 Java字节码.
其实,关于这个复杂的工具,还有很多要学习的内容,有关详细信息,请参见 甲骨文的规格.
您可能已经知道JVM是在各种操作系统上运行的抽象虚拟计算机。实际上,JVM使Java具有“平台独立性”,因为JVM充当了执行的代码和OS之间的抽象。
就像任何真实的计算机一样,JVM提供了一个 一套 指示 可由程序使用,稍后由JVM本身转换为机器特定的指令。
如中所述 JVM规范,Java虚拟机 什么都不知道 关于 Java编程语言. However, it defines the binary format class
 which is a file containing machine 指示 (= 通过 tecodes) to be executed (beside some more information). This is a very interesting point, because it actually means, that
- JVM不仅专用于Java作为一种编程语言。
- you are free to choose a technology for creating JVM programs as long as you provide proper
class
files that are compliant to the very strict constraints. - 无论使用哪种编程语言,任何Java字节码都可以与JVM上的其他Java字节码互操作。
创建类文件
科特林字节码生成-什么是Kotlin?
如官方所说 常见问题,“ 科特林产生Java兼容字节码”,这意味着Kotlin编译器能够将所有不错的功能转换为JVM兼容指令,甚至可以使用 IntelliJ IDEA 工具。
让我们看一些示例:
顶级功能
//File.kt
fun foobar(){}
可以使用IntelliJ研究在.kt文件中定义的此简单顶级功能:
“工具– 科特林 –显示Kotlin字节码” 将在IDE内打开一个新窗口,提供编译器将为当前编辑的Java字节码进行实时预览。 .kt文件.
public final class de/swirtz/kotlin/FileKt {
// access flags 0x19
public final static foobar()V
L0
LINENUMBER 3 L0
RETURN
L1
MAXSTACK = 0
MAXLOCALS = 0
@Lkotlin/Metadata;
// compiled from: File.kt
}
恐怕只有很少的人可以实际读取这些文件,这就是为什么我们也可以选择“反编译”选项的原因。然后,我们将向您提供一个Java类,其中包含了先前用Kotlin描述的功能:
public final class FileKt {
public static final void foobar() {
}
}
如您所见并且可能已经知道,Kotlin顶层类被编译为带有静态函数的最终Java类。 [1]。让我们来看一个更困难的:
类和扩展功能
class MyClass(val i: Int)
fun MyClass.myExtension(value: String) = value.length
This one shows a simple class MyClass
with a property
of type Int
, as well as a top level extension function.
首先,我们应该看一下将类编译成什么,这很有趣,因为我们使用了 主要建设者 和 val关键字 这里。
public final class MyClass {
private final int i;
public final int getI() {
return this.i;
}
public MyClass(int i) {
this.i = i;
}
}
As we would expect: the property
is a final
member being assigned in the single constructor. Yet, so much simpler in 科特林 🙂
public final class FileKt {
public static final int myExtension(@NotNull MyClass $receiver, @NotNull String value) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
Intrinsics.checkParameterIsNotNull(value, "value");
return value.length();
}
}
扩展函数本身通过它的编译为静态方法 接收对象 作为Java代码中的参数。
One thing we can also observe in the example is the use of a class called Intrinsics
. This one is part of the 科特林 标准库 和 is utilized because the parameters are required to be not null
.
Let’s see what would happen if we changed the inital extension function’s parameter to value: String?
和 of course access length
in a safe way.
public final class FileKt {
@Nullable
public static final Integer myExtension(@NotNull MyClass $receiver, @Nullable String value) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return value != null?Integer.valueOf(value.length()):null;
}
}
Checking value
is not necessary anymore since we told the 编译器 that null
is an acceptable thing to point to.
下一个示例有些棘手。它是Kotlin和Java代码之间最大的区别:
fun loopWithRange(){
for(i in 5 downTo 1 step 2){
print(i)
}
}
public static final void loopWithRange() {
IntProgression var10000 = 范围Kt.step(RangesKt.downTo(5, 1), 2);
int i = var10000.getFirst(); //i: 5
int var1 = var10000.getLast(); //var1: 1
int var2 = var10000.getStep(); //var2: -2
if(var2 > 0) {
if(i > var1) {
return;
}
} else if(i < var1) {
return;
}
while(true) {
System.out.print(i);
if(i == var1) {
return;
}
i += var2;
}
}
Although the Java code still is quite comprehensible, probably nobody would write it in real life, because a simple for
could do it, too. We need to consider that downTo
和 step
are 中缀符号,实际上是函数调用。为了提供这种灵活性,似乎只需要多一点代码即可。
你怎么看?尽管Kotlin代码非常出色,但看起来并不那么好,对吗?
结论
I think, most of the time you don’t really care 关于 what the 科特林 编译器 produces behind the scenes. Yet, I find observing it really interesting 和 helpful as it supports answering my initial questions in some way. It provides an answer to "What is 科特林" in a way 😉 Of course, 科特林 is much more than just abstracting Java’s operators since it also provides so many extensions to existing Java classes like List
or String
.
尽管如此,我们还看到有时编译的Java代码比必须的更为冗长。这会影响性能吗?是的,确实的,它的影响很小。看看这个 介绍 通过 德米特里·杰梅罗夫(Dmitry Jemerov) 如果您对更多考虑性能的“ 科特林 – Java字节码”示例感兴趣,
最后,如果您想了解Kotlin的美丽功能,我推荐这本书 行动中的科特林 给你!
让我知道您对此有何想法,如果您愿意,请保持联系!
Simon是总部位于德国的软件工程师,具有7年为JVM和JavaScript编写代码的经验。他’他对尽可能多地学习新事物充满热情,并且是科特林(Kotlin)的自发狂热者。
[…] >>JVM上的Kotlin –字节码生成[blog.simon-wirtz.de] […]
[…]希望快速介绍带有接收器的函数文字。这个概念使Kotlin非常适合设计特定于领域的语言,例如我们从Groovy知道的那样。另外,科特林斯[…]
[…]我想快速介绍一下Receiver的功能文字。这个概念使Kotlin非常适合设计特定于领域的语言,例如我们从Groovy知道的那样。另外,科特林斯[…]