Coming from other strongly-typed languages like Java or C#, the NullPointerException is one of the most common exceptions you can find, providing long debug sessions simply because a null reference was passed around and eventually called for.
Kotlin addressed this issue at a compiler-level, using it to throw errors when trying to assign a value to an object that has the potential to contain null values, *unless * you explicitly let kotlin know that is the intended behavior, and even then, you need a special syntax to access that object’s methods from thereon.
// Java and C# string str = null; // valid //Kotlin var str:String = null; // not valid
In the above code, you can see, kotlin doesn’t even allow the assignation of null value to a variable, if you wish to do so you must use a nullable type, which is kotlin’s way to tell the compiler that this variable has the potential to hold null values.
You indicate this adding a question mark at the end of the variable’s type, as follows
var str:String? = null; // valid
This code does compile and allows you to use variables holding null values in kotlin by stating it explicitly to the compiler that this is your intent.
Now, there is a catch. Remember the special syntax we talk about earlier? Well, now is the time to use it. You see, once a variable contains a nullable type you can’t use the dot notation anymore, so you must take one of two approaches when calling one the object’s methods or properties:
- Use the double bang syntax(!!) to access the method and throw a runtime exception if a null value is encountered.
- Use the safe-call syntax (?.) to access the method and return the null value (if encountered) while keeping the workflow of the program intact
// Alternative 1: Throw an exception var nullError:String? = null var count1 = nullError!!length() // Throws an exception // Alternative 2 : Return the null value var returnValue:String? = null var count2 = returnValue?.length // Returns the null value and keep the program running // dot notation var invalidSyntax:String? = null var count3 = invalidSyntax.length //Not valid for nullable types. A compile error is thrown
Although kotlin does not encourage the usage of null values, the language provides a null check operator for those cases where you must interact with them simplifying the code and making it more readable. The operator is called the Elvis operator (?:) and works as follows:
- Evaluate the expression at the right of the operator
- If it returns null, then evaluate and return the expression on the left side and return it
- If not, return the right side
// right side invalid var str:String? = null var count = str ?: "" // right side is null, evaluate and return the left side //right side valid var validStr:String = "Test" var count = validStr ?: "" // right side is not null, return the right side without evaluating the left
The approach to work with null values in kotlin is very pragmatic, you get compiler validation at the expense of not using null values unless explicitly stating it using special syntax which in turn makes you want to avoid them as much as possible and at it, preventing unwanted NullPointerExcepetions.
From my perspective, this is a great tradeoff. I know I won’t miss those exceptions one bit.
This post is part of a series aimed to give you an introduction to the language and a taste of the way kotlin does things. You can find it here: A guide to the kotlin language