Kotlin has Nothing but there is nothing like Nothing in Java

A pun-filled post on kotlin.Nothing type

Bob
Thoughts Overflow
4 min readAug 25, 2017

--

Nothing.

Before going to Nothing, first, let’s look at its sibling Unit.

Unit:

Unit in Kotlin corresponds to the void in Java. Like void, Unit is the return type of any function that does not return any meaningful value, and it is optional to mention the Unit as the return type. But unlike void, Unit is a real class (Singleton) with only one instance.

Nothing:

Nothing is a type in Kotlin that represents “a value that never exists”, that means just “no value at all”.

Nothing can be used as the return type of a function that never returns the code execution — like, looped forever or always throws Exception. Don’t get confused because Java does not have anything similar to the Nothing type.

So Kotlin has this fancy thing, what’s the big deal, you might ask.

Let me show you three examples of how the Nothing as the return type is useful.

For the below examples let’s assume there is a function reportError() which always throws a RuntimeException. In a real application, this reportError() might add some extra useful logs before throwing the exception or throws different exceptions based on different conditions.

reportError() in Java:

void reportError() {
throw new RuntimeException();
}

reportError() in Kotlin:

fun reportError(): Nothing {
throw RuntimeException()
}

Note that the Nothing has to be mentioned explicitly as the return type, otherwise the return type would still be Unit.

1. Unreachable code

What will happen if we mistakenly put some code after calling this reportError() method?

In Java, nothing will happen.

// Javaint i = 0;void exampleOne() {    reportError(); // throws RuntimeException    i = 1; // This is unreachable code. But there is no warning.}

In Kotlin, something good happens because of the Nothing.

// Kotlinvar i = 0;fun exampleOne() {    reportError(); // throws RuntimeException    i = 1; // We will get an 'Unreachable code' warning here. }

There is a warning “Unreachable Code” in Kotlin, whereas Java compiler has no idea about that. And Kotlin saves us from a potential bug using Nothing.

2. Throw in a conditional ternary operator:

What will happen if we call reportError() in a conditional ternary operator?

We will get a compile error “Incompatible types” in Java, as the reportError returns void and we are trying to save it in a String.

// Javavoid exampleTwo(Map<String, String> map) {

String data = map.containsKey("key") ? map.get("key") : reportError(); // Won't compile - 'Incompatible types' error.
}

In Kotlin (using the Elvis operator as there is no conditional ternary operator, yet):

// Kotlinfun exampleTwo(map: Map<String, String>) {

val data: String = map["key"] ?: reportError() // Compiles! Note the type is String.
}

It results in a compile error in Java, as the compiler couldn’t figure out that the reportError() will never return. But it’s not a problem for Kotlin compiler as it has Nothing.

3. Throw in a method that has a meaningful return type:

What will happen if we call the reportError() in a method that has a return type other than void or Unit?

In Java, we will get a “Missing return statement” error.

// JavaString exampleThree(int n) {    if (n > 5) {
return "Ok";
}
reportError(); // Won't compile - 'Missing return statement' error. }

In Kotlin, no issues:

// Kotlinfun exampleThree(n: Int): String {    if (n > 5) {
return "Ok";
}
reportError(); // throws RuntimeException // Compiles!}

Personally, I have been annoyed quite a few times with the above issue while working in Java. I had to put fake return statements — like, return null or return -1 — to workaround the “Missing return statement” error.

So remember to use Nothing whenever the functions don’t return anything.

Please leave your thoughts in the comments or reach me on Twitter.

--

--