kotlin在JVM上– Bytecode Generation

kotlin在JVM上 - 它如何提供这么多功能?

介绍

究竟是什么 “JVM语言”,kotlin是什么? Java不仅是在JVM上运行的吗?
kotlin. 提供了java中不可用的许多功能,例如正确 功能类型, 扩展功能数据类。这甚至是如何?我越来越深看着Kotlin如何在引擎盖下工作以及“JVM语言”的实际意味着什么。我们将看看Kotlin的字节码生成。如果您还考虑过这些事情,这篇文章应该将一些光线带入黑暗中 -

有更详细的介绍 kotlin的特色 你可以看看我的 入门指南.

Java虚拟机

快速而简单的定义: 这 Java虚拟机 计算机用于运行 Java Bytecode..
实际上还有很多东西可以了解这个复杂的工具,这是广泛描述的 甲骨文的规格.

正如您所知道的,JVM是一个在各种操作系统上运行的抽象虚拟计算机。事实上,JVM是使Java“平台独立”的原因,因为它作为所执行的代码和操作系统之间的抽象。
就像任何真正的计算机一样,JVM提供了定义的 指示 可以由程序使用,并且稍后将通过JVM本身转换为机器特定说明。

如上所述 JVM规范,Java虚拟机 什么都不知道 关于 编程语言Java. However, it defines the binary format class which is a file containing machine instructions (= bytecodes) to be executed (beside some more information). This is a very interesting point, because it actually means, that

  1. JVM不仅专用于Java作为编程语言。
  2. 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.
  3. 无论编程语言如何,任何Java字节码都可以在JVM上与其他Java字节码互操作。

创建类文件

从人类可读源代码创建类文件的过程是什么 编译器 做。一个例子是Oracle的Java编译器附带 jdk. (javac) that is capable of compiling .java files to .class files.
除了Java,还有许多其他 JVM语言 在过去几年中出现了,所有这些都尝试为开发人员提供替代抽象,以创建JVM的程序。
其中一种语言是 kotlin..

kotlin.字节码生成 - Kotlin是什么?

正如官员所述 常见问题解答,“Kotlin生成Java兼容字节码”,这意味着Kotlin编译器能够将所有良好功能转换为JVM兼容指令,甚至可以使用 intellij想法 tools.
让我们来看看一些例子:

顶级功能

kotlin.
//File.kt
fun foobar(){}

可以使用Intellij调查.kt文件中定义的简单顶级函数:
“工具→Kotlin→Show Kotlin Bytecode” 将在IDE内打开一个新窗口,提供Java字节码的实时预览编译器将为当前编辑创建 .kt文件.

Java Bytecode.
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
}

我担心只有少数人实际上可以阅读这些文件,这就是我们也可以选择“Decompile”选项的原因。之后,我们将被呈现一个封装先前用Kotlin描述的功能的Java类:

顶级功能不编译
public final class FileKt {
   public static final void foobar() {
   }
}

如您所见并可能已经知道,Kotlin顶级类是用静态函数编译成最终Java类的kotlin顶级类 [1]。让我们看看更加困难的一个:

类和扩展功能

kotlin.
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关键字 here.

java的课程
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 Kotlin 🙂

扩展功能对分解
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 Kotlin stdlib. 和 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 compiler that null is an acceptable thing to point to.
下一个例子有点棘手。这是Kotlin和Java代码之间最大的差异:

范围
kotlin.
fun loopWithRange(){
    for(i in 5 downTo 1 step 2){
        print(i)
    }
}
反编译
 public static final void loopWithRange() {
      IntProgression var10000 = RangesKt.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 downTostep are infix符号,实际上是函数调用。为了提供这种灵活性,似乎需要更多的代码。

你怎么看?它看起来不太好,虽然kotlin代码很棒,对吧?

结论

I think, most of the time you don’t really care about what the Kotlin compiler produces behind the scenes. Yet, I find observing it really interesting and helpful as it supports answering my initial questions in some way. It provides an answer to "What is Kotlin" in a way 😉 Of course, Kotlin 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代码比必须更冗长。这可能会发生这种影响吗?是的,实际上,它确实有很小的影响。看看这个 介绍 经过 德米特里·杰米洛夫 如果您对更多的“Kotlin→Java Bytecode”的示例也会考虑性能感兴趣。

最后,如果你想阅读Kotlin的美丽功能,我推荐这本书 kotlin在行动中 to you!

让我知道你对它的看法,如果你愿意,请联系!


 1。此结构看起来像什么扩展函数意味着替换:实用程序类

3 thoughts on “kotlin在JVM上– Bytecode Generation

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *