Kotlin: Uncovered - Part 1
Learning about Kotlin through decompilation
Coding at desk by Negative Space is licensed under Creative Commons Zero
Have you gotten a chance to work with Kotlin yet? I encourage you to check it out.
Kotlin is a programming language developed by JetBrains. It is a functional, statically typed language for the JVM, Android, and the browser. What does all this mean though?
Statically Typed
Kotlin is a statically typed language, which means we get the same type safety we get in Java. It also means we get the same great IDE autocompletion because of the static analysis. Where it differs from Java is that Kotlin can infer types. Because of this, we don’t need to specify the type of a variable if we assign it when we declare it.
// Java final String name = "Victoria";
// Kotlin val name = "Victoria"
Null Safety
Kotlin also has null
safety built right into the type system. With this, we always know if a variable could be null
. If the value could be null
, the compiler forces us to check for it before we perform any operations on it. This greatly reduces our risk for NullPointerException
s. I’m happy to live without those.
Concise
Some other things I enjoy about Kotlin are the functional programming features and boilerplate reduction. If you haven’t heard, it’s much more concise than Java. It’s also not terse in the way that can make some languages unreadable.
# Perl map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}
You’ll often find the Kotlin is delightfully concise.
// java int[] array = {1, 2, 3}; int[] dest = new int[3]; for (int i = 0; i < array.length; i++) { dest[i] = array[i] * array[i]; }
// kotlin var array = listOf(1,2,3) var dest = array.map { it * it }
Interoperable
JetBrains worked hard to make Kotlin interoperable with Java. You can easily call Kotlin from your Java code, and call Java from your Kotlin code. Most of the time, the interoperability is seamless. When it’s not, Kotlin provides JVM annotations to make Kotlin code translate to more idiomatic Java. What’s helpful is that Kotlin gets compiled down to the exact same bytecode for the Java Virtual Machine to run as Java.
Decompiling
Because they both compile to the same bytecode, we can decompile Kotlin into Java. JetBrains has made this easy to do in IntelliJ. Assuming you have the plugin installed and the dependency added, you can go to Menu > Tools > Kotlin > Show Kotlin Bytecode, or CMD + SHFT + A and search “Show Kotlin Bytecode”. On that window there is a button “Decompile” if you have a Kotlin file open. By clicking it, you get the equivalent Java from the Kotlin bytecode.
By decompiling Kotlin bytecode into Java, we can learn more about the language and understand how it works. Coming from Java, some of the concepts in Kotlin can seem foreign. It’s a bit of a paradigm shift. Through investigating the equivalent Java, we have another tool to help us wrap our heads around what Kotlin can do for us.
I first heard about decompiling Kotlin from this blog post by Piotr Ślesarew about Kotlin delegation. Reading it made me excited about the delegation, but even more excited to try out this decompiling thing he showed. I had lots of fun with it, making it a guessing game about what the Java would be after I decompiled. But I also learned a ton.
Follow along this blog post series as I show you the many things you can learn from decompiling Kotlin.
Continue to Part 2.
Comments
Just looking at that map function in Kotlin makes me all happy.
Just looking at that map function in Kotlin makes me all happy.
Kotlin is a really nice language and I’m enjoying learning it, going through the Kotlin Koans, etc. Only thing I’d suggest here is not to compare Java using imperative loop structures to Kotlin. Java 8 has been out for a long time (years) and the Stream API makes mapping transformations, filtering, etc. much nicer. So while the equivalent Kotlin will still be more concise, the Java Stream API comes somewhat close and isn’t all that bad anymore, e.g. assuming you have a list of integers named “numbers” you can do: numbers.stream().map(num -> num * num).collect(toList())
Really enjoying your series on Kotlin! Very well explained, and makes me excited to learn more!
the gamephoto