Kotlin has Nothing but there is nothing like Nothing in Java
A pun-filled post on kotlin.Nothing type
![](https://cdn-images-1.medium.com/max/1600/1*TNeuk9C_SnVZzpI01HZvrQ.jpeg)
Before going to Nothing
, first, let’s look at its sibling 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.
// Java
int 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.
// Kotlin
var 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.
// Java
void 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):
// Kotlin
fun 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.
// Java
String exampleThree(int n) {
if (n > 5) { return "Ok"; }
reportError();
// Won't compile - 'Missing return statement' error.
}
In Kotlin, no issues:
// Kotlin
fun 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.