Subbu Lakshmanan

Simple, yet powerful features of Kotlin

How Kotlin Improves the Handling of Null Values

I read about Kotlin, the simple, yet powerful language which can be Java alternative years ago when Jetbrains released their initial versions of Kotlin. Having worked on Java for longer time, I called it "blasphemy", and totally ignored it.

However ever since the Kotlin was announced as offical programming language for Android in Google I/O, I realized that I have been silly all these time and biased towards Kotlin. I felt stupid for not realizing it sooner and have started spending time in learning Kotlin.

I'm currently going through the pluralsight course, Kotlin Fundamentals by Kevin Jones. As he was explaining "How Kotlin Improves the Handling of Null Values", I realized the simple, yet powerful feature of Kotlin in handling the 'null' and how it can help java developer from frustrating null check.

Funny Null Pointer

In Java

In Java by default any variable declared can be null. For example,

class Developer {
    String team;
    String role;
    String project;

    void display(String name, String employeeType) {
        if (employeeType.equals("Full-Time")) {
            System.out.println(name + " is a Full-Time " + role + " in " + team + " working in " + project);
        } else {
            System.out.println(name + " is a Intern "+ role + " in " + team + " working in " + project);
        }
    }
}

class LearningKotlinUtil {

    public static void main(String[] args) {
        Developer dev = new Developer();
        dev.project = "ePhone7";
        dev.team = "Mobile Team";
        dev.role = "Android Developer";
        
        dev.display("Subbu", "Full-Time");

        dev.display("Subbu", null);
    }
}

In the Developer class, type can be null. So the second invocation to 'display()' method will throw a NullPointerException. To avoid that, the developer has to do null-check as below.

class Developer {
    ...
    void display(String name) {
        if (employeeType != null && employeeType.equals("Full-Time")) {
            ...
        } else {
            ...
        }
    }
}

or you can write as below,

class Developer {
    ...
    void display(String name, String employeeType) {
        if ("Full-time".equals(employeeType)) {
            ...
        } else {
            ...
        }
    }
}

To take advantage of IDE features, the developer can annotate the variable type with @NonNull annotation as below.

class Developer {
    ...

    void display(String name, @NonNull String employeeType) {
        if (employeeType != null && employeeType.equals("Full-Time")) {
            ...
        } else {
            ...
        }
    }
}

@NonNull annotation is supported through android annotation support library or Java 8 Annotation Support JSR-308. import android.support.annotation.NonNull;

Now the IDE (Intellij/Android Studio) warns the developer as in the below screenshots, Assigning Null Null-Check

However it doesn't prevent the variable 'type' being set to 'null' and the developer must listen to the IDE(if using one) warnings. If the developer isn't careful, the null-pointer can only be realized in runtime.

Kotlin to Rescue

In Kotlin, by default the variables var is of non-null type the type system defines whether the variables can hold 'null' or not. For example, here when you declare employeeType as 'employeeType: String', the Kotlin type system enforces employeeType variable as non-nullable.

class Developer {
    var team: String = ""
    var role: String = ""
    var project: String = ""

    fun display(name: String, employeeType: String){
        if(employeeType == "Full-Time") {
            println("$name is a Full Time $role in $team working in the $project project")
        } else {
            println("$name is a Intern $role in $team working in the $project project")
        }
    }
}

fun main(args: Array<String>) {
    val dev = Developer()
    dev.team = "Mobile Team"
    dev.role = "Android Developer"
    dev.project = "ePhone7"

    dev.display("Subbu", "Full-Time")
}

Now the parameter, 'employeeType' can never be null and attempting to do so will result in compilation error.

fun main(args: Array<String>) {
    val dev = Developer()
    dev.team = "Mobile Team"
    dev.role = "Android Developer"
    dev.project = "ePhone7"

    dev.display("Subbu", "Full-Time")
    dev.display("Subbu", null)
}

Compilation Error

If you really want to allow employeeType to accept 'null' values, you must explicitly states so as below using '?' operator.

If the 'employeeType' variable can have 'null' values, it should be declared as 'String?' as per the Kotlin Type system.

class Developer {
    ...
    fun display(name: String, employeeType: String?){
        ...
    }
}

The declaration 'employeeType: String?' tells that the compiler that employeeType can accept 'null' as value. This is equivalent to @Nullable annotation in java.

This is one of the powerful features of Kotlin. Making the variables as 'Non-Null' by default and forcing the developer to explictly declare variables that can be 'null', 1. Indirectly forces the developer to think about the variables usage when declaring one 2. It prevents the developer attempting to assign/pass 'null' in compilation time itself.

I have just kick-started learning Kotlin, and I will keep posting new simple, yet powerful features of Kotlin as I explore them.

In my humble opinion, a better understanding of Kotlin type system will greatly assist the developer to think about the values that a variable can hold at the declaration and also prevent other developers to pass/assign 'null' values even by mistake.

I have just kick started learning Kotlin, and I will write further blogs about the features that I liked, once I understood them completely. Please feel free to throw in any comments or suggestions.

This post is also available on DEV.

All rights reserved