Inspecting Kotlin Bytecode

You learned in Chapter 1 that Kotlin is an alternative to Java for writing programs that run on the JVM, where Java bytecode is executed. It is often useful to inspect the Java bytecode that the Kotlin compiler generates to run on the JVM. You will look at the bytecode in several places in this book as a way to analyze how a particular language feature works on the JVM.

Knowing how to inspect the Java equivalent of the Kotlin code you write is a great technique for understanding how Kotlin works, especially if you have Java experience. If you do not have Java experience specifically, the Java code will likely share familiar traits with a language that you have worked with – so think of it as a pseudocode to aid your understanding. And, if you are brand new to programming – congratulations! In choosing Kotlin, you have chosen a language that, as you will see in these sections, allows you to express the same logic that Java does, typically in much less code.

For example, you may have wondered how using type inference when defining variables in Kotlin affects the resulting bytecode that is generated to run on the JVM. To learn how, you can use the Kotlin bytecode tool window.

In TypeIntro.kt, press the Shift key twice to open the Search Everywhere dialog. Begin entering show kotlin bytecode in the search box, and select Show Kotlin Bytecode from the list of available actions when it appears (Figure 2.9).

Figure 2.9  Showing Kotlin bytecode

Showing Kotlin bytecode

The Kotlin bytecode tool window will open (Figure 2.10). (You can also open the tool window with ToolsKotlinShow Kotlin Bytecode.)

Figure 2.10  Kotlin bytecode tool window

Kotlin bytecode tool window

If bytecode is not your native tongue, fear not! You can translate the bytecode back to Java to see it represented in terms you may be more familiar with. In the bytecode tool window, click the Decompile button at the top left.

A new tab will open showing TypeIntro.decompiled.java (Figure 2.11), a Java version of the bytecode the Kotlin compiler generated for the JVM.

Figure 2.11  Decompiled bytecode

Decompiled bytecode

(The red underlines in this case are due to a quirk in the interaction between Kotlin and Java, rather than a problem.)

Focus on the variable declarations for experiencePoints and playerName:

      String playerName = "Estragon";
      int experiencePoints = 5;

Although you omitted type declarations from the definitions of both variables in the Kotlin source, the bytecode that was generated includes explicit type definitions. This is how the variables would be declared in Java, and the bytecode gives a behind-the-scenes look at Kotlin’s type inference support.

You will dig deeper into the decompiled Java bytecode in later chapters. For now, close TypeIntro.decompiled.java (using the X in its tab) and the bytecode tool window (using the Decompiled bytecode icon at the top right).

In this chapter, you have learned how to store basic data in vars and vals and seen when to use each, depending on whether you need to be able to change their values. You have seen how to declare immutable values using compile-time constants. Last, you learned how Kotlin leverages the power of type inference to save you keystrokes every time you declare a variable. You will be using all these basic tools over and over as you proceed through this book.

In the next chapter, you will learn how to represent more complex states using conditionals.