Kotlin Under the hood: the magic of classes. Part 1

Nazarii Moshenskyi
5 min readMar 15, 2020

Nowadays, Kotlin becomes a more and more popular language for Android Development that’s why we start Kotlin Under the hood. We will go through different aspects of Kotlin to ease the transition from Java to Kotlin.

In this article, we will discover the main part of the Java world — classes. Let’s go!

During development, especially in production code, our classes grow exponentially. In one moment your class can turn into thousands of lines of code which makes debugging and refactoring too complex. Kotlin reduces boilerplate code, variable and method creation.

We will create a class and change it in each example. I will use standard Kotlin Bytecode Decompiler(to generate Java code from Kotlin) which is built-in into Android Studio. If you want to learn how to use it — refer to my article.

Example #1: Field initialization

Let’s create a class Car with fields horsePower and numberOfDoors.

Car and Engine classes in Kotlin

Take a look at arguments passed to Car constructor, one of them private val. It means that we want to create a field for it and this variable will be final. For the first argument, we will not create a special field. It will live only in a constructor, so we are not going to mark it like var or val.

Now using Kotlin bytecode decompiler we will convert this class to Java(I will omit meta-info):

Car and Engine classes in Java

As you might notice Java classes are bigger because of extra lines of code for field creation and initialization. Kotlin does it for us. We don’t need to waste much space in our class to create a constructor for such a dumb logic.

Example #2: Getters and setters

You may be wondered why I pass the value into the constructor, store it inside a class but don’t create accessor methods for it. So, let’s do it.

Car with a getter(Kotlin)

What changed? private val numberOfDoors changed to just val numberOfDoors. Now it will create a getter. Let’s see:

Car with a getter(Java)

So, where is a setter? In Kotlin we have 2 main keywords for declaring a variable: val and var. val is immutable. It means that we can’t assign it to another instance. That’s why we don’t see a setter for val numberOfDoors.To create a setter just change val to var:

Car with getter and setter(Kotlin)

Take a look at the field engine, it’s not passed as a constructor parameter, so we created it directly inside our class.

And after converting it to Java we will see our getter and setter methods:

Car with getter and setter(Java)

Example #3: Custom getters and setters

Of course, you can create your custom getters and setters. You just need to init the desired field with constructor argument and write custom accessor methods:

Custom accessor methods(Kotlin)

Here field operates with a value stored inside. So, inside a setter we assign field a value(read as “saves the value to numberOfDoors”), in getter — we return field(read as “return the value of numberOfDoors”).

If we convert it to Java, we will get something like this:

Custom accessor methods(Java)

Example #4: equals, hashCode, toString

It’s actually a lot of boilerplate code to write these methods. Let’s generate it with adding keyword data before class declaration:

Data class(Kotlin)

A pretty small amount of code. How it will look in Java?

Data class(Java)

Wow! 3 lines of code in Kotlin replaces 50 lines in Java. It will help you to keep your class clean and easily maintainable. If it was class with some extra-logic, you would waste lots of time to find something in such a big codebase.

Example #5: Custom logic in the constructor

As you might notice, there is no space for constructor logic here:

As you already know, we actually have a constructor. I showed it in the very first example. Now, I gonna show you how to add additional logic to this constructor:

Custom Constructor(Kotlin)

So, nice. But will these print before or after variable initialization? Let’s check it out in decompiled Java code:

Custom Constructor(Java)

Well done. We’ ve just figured out that all statements and expressions are being added to constructor right after field initialization.

In the next part of Kotlin Under the hood: the magic of classes. We will demystify multiple constructors in a class, open and sealed classes and lateinit modifier.

📝 Save this story in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--