Benefits of Kotlin over Java: Backend and Android

Benefits of Kotlin over Java: Backend and Android

Ever since I have shifted to Kotlin I have never looked back!

Subscribe to my newsletter and never miss my upcoming articles

Before We Begin

I have been using Kotlin for a while now and I believe it has the right set of features for developers. I will be sharing the features that worked really well for both Spring Boot Backend and Android. But before getting into that, let's start from the basics.

What is Kotlin?

Kotlin is a general-purpose, open-source, statically typed programming language for the JVM, Browser, Native, and Android that combines object-oriented and functional programming features.

Fun Fact

The name comes from Kotlin Island, near St. Petersburg. Andrey Breslav mentioned that the team decided to name it after an island just like Java was named after the Indonesian island of Java.

Some More facts

  • Kotlin’s growth has been doubling each year until 2015 when the first massive spike in its usage happened.

  • Google announced that Kotlin was officially supported for Android and a massive number of Android developers started using Kotlin.

  • It’s taken seriously by Gradle build tool

  • Old-time players like Spring are supporting Kotlin

  • In the official studies conducted by JetBrains, two questions were asked and these were the outcomes.

1. How do you mostly use Kotlin?

Source: [](

2. What’s stopping you from using Kotlin in production?

Source: Source: []( Source:

It is clearly visible that a lot of people have already started using it in production. And the major reason for people to not use it is the lack of knowledge. I hope this blog post can help reduce the “lack of knowledge” percentage and make people more comfortable using Kotlin in production.

Null Safety Is A Blessing

This is one of the best features of Kotlin. It reduces so much overhead for a developer and makes you write code that is safe. Kotlin’s type system is aimed at eliminating the danger of null references from code, also known as The Billion Dollar Mistake.

We can still have fields that can be null but we have to explicitly declare that and that's how the compiler will always complain if you do not handle it properly.

The problem with the NPE (Null Pointer Exception) is its ability to creep in the codebase. And more often than not your application throws it during runtime when your users are actually using the app.

With the safe operator ?. , you can easily handle that explicitly.

 if (text != null) { 
   int length = text.length(); 

 text?.let { 
     val length = text.length 
 // or simply 
 val length = text?.length

And to handle the null case you can use Elvis operator ?:

val result = nullableVariable**?.**someMethodCall()
                       **?:** fallbackIfNullMethodCall()

Sealed Classes for Restricted Hierarchies

Sealed classes are Kotlin’s way of providing you a way to limit the types of a class when a value can have one of the types from a limited set.

sealed **class** Operation {
**    class** Add(val value: Int) : Operation()
**    class** Substract(val value: Int) : Operation()

And then simply use the when expression to evaluate conditions for each of the types. If you miss any type, the compiler will complain. This reduces the amount of code you write

fun **execute**(x: Int, op: Operation) = **when** (op) {
    **is** Operation.Add -> x + op.value
    **is** Operation.Substract -> x - op.value

Most of the backend codebases will have some sort of analytics tracking to track the behaviour of your users or system. Using sealed classes to create a set of events that you would trigger would be a good way to ensure all the events have a consistent format. The when expression will then ensure that you have not missed any of the Events during compile time.

Another good use of sealed classes in Android is to handle the UI states. Let’s say you have three states for your activity — Loading, Data, NoData. You can create a sealed class UIState and handle them in the activity. You can learn more about using sealed classes for Android here.

Immutability is the Default Setting

In Kotlin, we should always use val to declare a variable. This creates an immutable variable. In Java, we have to add the additional keyword final (again, syntactic noise!). If your variable really has to be mutable, you can use var. But think twice before you use var.

**val** immutableName = "Name"
immutableName = "New name" *// compile error! 
***var **mutableName** **= "Name"
mutableName = "New Name"

As a developer, you gain a lot of confidence writing code when you know your variables are not going to be manipulated unless you declare them like that.

Just like variable reference, collections are immutable by default, and data classes are immutable as well.

val list = *listOf*(1,2,3,4) 
list.add(1) *//compile error.*

You still have the mutable collections which can be declared prefixing mutable in front of the collection.

val list = *mutableListOf*(1,2,3,4)

Late Initialization of Properties

The modifier **lateinit* allows us to delay the initialization of a variable. Very useful when the dependencies are initialized by the DI (Dependency Injection) framework*, which happens during runtime.

It comes in very handy for testing as most of the classes are mocked. Like in the case of Spring Boot when your dependencies are provided by Spring.

lateinit var myRepository: MyRepository

If you use Dagger, you might be used to code snippets similar to the following one:

lateinit var myVar: MyObject

The variable is actually not initialized but injected afterward. By using **lateinit** we allow the initialization to happen later. This reduces the number of unnecessary null checks.

Less Boilerplate is Definitely a Plus

This is one of the first arguments that favour Kotlin in a huge way. Kotlin reduces a lot of code that you write and never look at. It is designed very well for major use cases. For example, data classes readily provide equals, hashCode, toString, and copy functions.

// Java

public class Price {
    String amount;
    String currency;

    public Price(String amount, String currency) {
        this.amount = amount;
        this.currency = currency;

    public String getAmount() {
        return amount;

    public void setAmount(String amount) {
        this.amount = amount;

    public String getCurrency() {
        return currency;

    public void setCurrency(String currency) {
        this.currency = currency;

// Kotlin

data class Price(val amount: String, val currency: String)

Few Things to Be Aware Of

  • I have faced a few issues with using Hibernate with Kotlin because all the classes are final by default. To circumvent that you need to add a few dependencies and plugins. Here is the link that has detailed information.

  • Name shadowing can really turn into a nightmare at times, and those are only warnings from the compiler. When your code becomes too nested, it becomes harder to read.

  • Kotlin did a good job of reducing the boilerplate code and make everything concise, but that sometimes leads to very high information density.

Final Thoughts

The more I write applications with Kotlin, the more I feel comfortable with it. It has allowed me to write applications more efficiently with expressive, short, and readable code, and using it has been a real pleasure.

And just like any other language, when you start it for the first time, it feels confusing and alien. But Kotlin looked the least confusing, most constructs were pretty easy to understand and remember. I have worked in Java, Go, and a little bit of Python, but this one has been my favorite to date.

I absolutely recommend learning it and using it.

Links to popular Kotlin concepts.

  1. Kotlin standard functions

  2. [var, val, lateinit, lazy](

  3. Sealed classed for Android

  4. Using final classes with Hibernate

Share this