Kotlin null safety explained19 Jun 2017
In my Java developer’s career, NullPointerException is the single most common runtime error I encounter. And according to this research, I’m not an exception (pun intended!). Even the inventor of null reference, computer science pioneer Tony Hoare called it The Billion Dollar Mistake.
Fortunately, Kotlin introduces the concept of null safety. If you are using pure Kotlin (without mixing it with Java code) you encounter two types of references:
- The Non-Null type:
The non-null string’s type is written as
- The Nullable type:
The nullable string’s type is written as
'String?', with question mark suffix
This way we’re sure that the non-null reference will never throw dreaded NullPointerException. But what happens if we try to call some function on the nullable reference? It won’t happen because it will not compile. The compiler doesn’t care if the reference is null or not:
We can’t call functions on nullable references without explicitly handling the nullability. There are 3 basic ways to do that:
- “Classic” null check:
This is the exact same way as every Java coder did thousands of times. Compiler knows all the uses of our
nullableReference inside the
if block are safe, cause we checked it’s not null before the calls are being made.
- Safe call:
The Kotlin safe calls are being made using the special operator
'?.' - in our case, the expression
println(nullableReference?.length) will not crash at runtime but instead return
null. If the
nullableReference wasn’t null it would return the string’s length as
'Int?' (which itself is a nullable integer).
- Non-null asserted call:
While using a double exclamation mark (a.k.a “double bang”) we are stating that we’re 100% sure our
nullableReference is not null. This is the same behaviour as classic Java call without doing null-check. In our case, the app will crash and the NullPointerException will be thrown! This notation was made ugly on purpose, it is basically an indicator of code smell and should be used only when you want your app crash at runtime whenever there’s null reference. In most cases you should either:
- Use non-nullable types whenever possible or
- If you are using nullable type, do a safe call or a null-check
But what if we are mixing Kotlin with Java?
Fortunately, when our Java code is properly annotated it will behave exactly the same as Kotlin code. Kotlin compiler recognizes many popular annotation frameworks, including Android annotations framework. If developer properly annotates the code with
'@Nullable' annotations, the compiler will see those references as if they were Kotlin types. Fortunately for us mobile developers, Android framework and many popular libraries are already annotated properly.
If for whatever reason the Java code you are using wasn’t annotated, Kotlin introduces the concept of platform types. This means that whenever you are using such code, it will be treated the same as in Java. This was done for convenience (so the code wouldn’t be filled with question marks and double-bangs). The platform type string is marked as