Why Java programmers should use Kotlin (or at least try it)

Rein Krul

Rein Krul

Published: 18 September, 2017

Kotlin has been around for a while now, but hasn't been getting the attention it deserves. Stack Overflow makes this painfully obvious:

(Source: Stack Overflow)

For every Kotlin-related question on Stackoverflow, people ask 30 Java-related questions. On the other side, it's not a bad score for a language that had its 1.0 birthday last year. Kotlin clearly isn't the latest fad for hipster programmers (do those actually exist?).

This article is meant for you: the Java programmer who hasn't heard of Kotlin (or tried it), and is eager to make his day-to-day Java programming easier.

So, why should you try it?

1. It's easy to learn

Having a Java background, I was able to write Kotlin almost instantly. For example, take a simple 'Hello, World!' program:

public class HelloWorld {
    public static void main(String... args) {
        System.out.println("Hello, World!");
    }
}

In Kotlin, it becomes:

fun main(args: Array<String>) = println("Hello, World!")

Notice a few things here:

  1. There are no accolades: these are optional for one-liners, enabling a functional programming style.
  2. There is no class definition: functions can exist outside of classes.
  3. Writing functions is 'fun' (pun intended).
  4. Semicolons are obsolete.
  5. As a hard-core Java programmer, I can understand it!

2. It runs on the JVM

The JVM has proven to be a great platform for languages other than Java, both functional and procedural; (e.g.: Clojure, Groovy, Scala, Jython, JRuby, etc). It's mature, runs on almost any platform and there are loads of debugging/monitoring tools.

3. Awesome build tool integration

Although you can run the Kotlin compiler as a standalone Command Line utility, there is support for Ant, Maven, Gradle and Griffon. Since it is backed by JetBrains (known for their top-of-the-line developer tools) more can be expected in future.

4. Full compatibility with Java libraries

You can call any Java code from your Kotlin application the same way you call Kotlin code. Calling Kotlin code from Java is just as easy although there are some things to consider, because there are constructs in Kotlin that don't exist in Java.

5. Null safety

Kotlin allows you to write code that is null safe; think Elm's Maybe or Java 8's Optional. By default, values or variables are non-nullable unless you specify it as being nullable:

data class Record(val name: String)
val record = Record(null) // Compile error!

Consuming potential null values leads to compiler errors:

fun retrieveName(): String? = null // Notice the ? (question mark), indicating the result may be null
fun execute() {
    val name = retrieveName()
    val nameLength = name.length // Compile error! 'name' might be null
    if (name != null) {
        val nameLength = name.length // This compiles (null has been checked)
    }
}

Unfortunately, we're not entirely cured from NullPointerExceptions. When dereferencing a Java type (for which Kotlin has no notion about nullability), you still have to explicitly check for null values:

fun openUrl(url: String) = 
    URL(url).openConnection()?.connect() // openConnection() might return null, so use the question mark to call connect() safely 

6. Google believes in it

Google recommends you to use it when developing for Android, so why not stick to their advice?

7. It's fun to write

Writing code that is clean, expressive, no-nonsense and maintainable is fun, the opposite (messy, redundant, wrong kind of verbosity) isn't. That's why you should write code using Kotlin.

import java.io.File
import java.nio.file.Files
import java.nio.file.Paths

fun fileToStdOut(fileName: String) =
    File(fileName)
        .inputStream()
        .reader()
        .use { println(it.readText()) }

or:

import java.nio.file.Files
import java.nio.file.Paths

fun fileToStdOut(fileName: String) =
    println(String(Files.readAllBytes(Paths.get(fileName)), Charsets.UTF_8))

The Java-equivalent would be:

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Example {
    public void fileToStdOut(final String fileName) throws IOException {
        if (fileName == null) {
            throw new IllegalArgumentException("fileName is null");
        }
        final String text = new String(Files.readAllBytes(Paths.get(fileName)), Charset.forName("UTF-8"));
        System.out.println(text);
    }
}

8. It also compiles to JavaScript and Native

Beside the JVM, Kotlin compiles to Javascript and native code. Not that I felt the need (yet), but it's nice to have the options.

9. Singleton is a language construct

No more poorly implemented singletons: Kotlin's 'object' keyword transforms a class into a singleton.

interface State {
    fun report()
}

object StaticState : State {
    override fun report() = println("This is a singleton.")
}

class Application(val state: State) {
    fun run() = state.report()
}

fun main() = Application(StaticState).run()

A few things are happening here:

  1. We have an interface 'State', just like we would have in Java.
  2. We have an object (singleton) which implements this interface.
  3. We provide an implementation of this interface to our Application class, just by referencing the object (no additional invocation/instantiation required).

What's next?

That's it!

Related blogs

Did you enjoy reading?

Share this blog with your audience!