Null Safety: Non-null Types and Nullability in Kotlin
Content Index
One of the problems we face when developing applications in many of today's programming languages such as C#, Java, and our case of interest, which is developing applications with Android, is the more than annoying NULLPointerException from Java or the Null Reference Exception that can appear in our application when we least expect it; Kotlin offers several very interesting methods to deal with this annoying scenario with very little code and in a very easy way.
Previously, we saw how to use variables, data types, mutable and immutable, and Operators in Kotlin.
️ Null Safety
Null safety, or protection against the famous NullPointerException, is a fundamental piece in any modern high-level programming language, such as Kotlin.
One of the most common errors when programming is a "blessed null" popping up. For example, in low-level languages like C, practically everything can lead to an error of this type. To avoid these problems, Kotlin integrates nullability directly into its type system.
In this post, we will see how to handle non-nullable data types (which are not allowed to be null), those that can be null, and how to handle what would be a NULLPointerException in Java within Kotlin.
Non-nullable types
By default, data types in Kotlin are not allowed to be null, which in itself is a good idea since the compiler will warn us if at any time we programmatically set (in the code) said variable as null:
var a: String = "abc"If we try to reference a null value:
var a: String = "abc"
a = null // compiler errorThe compiler would give us an error; the problem arises if the value comes from some other source such as input data or a server provided by a query (in short, at runtime), etc., which could give us a null value for this variable. For these cases, and when we want our variable to be able to be null, we must do what is explained in the following section.
Variable declaration and the use of ?
If you try to assign null to a normal variable, the compiler will throw an exception indicating that it is not allowed. However, many times we need a variable to be able to be null (for example, when receiving data from an API). To do this, we add a question mark after the data type:
var a: String? = "abc"
a = null // the compiler allows itOf course, with this we return to the initial problem with null references in the properties and methods that we can use in our defined variables, and with this, the initial problem in a cycle that seems to have no end... or does it?
The Kotlin compiler forces us to check if a variable is defined as NULLable or that it can be null before using a property or method of it; that is, if we have the following code snippet:
val x: Int? = nullAnd try to use some method or property:
val h = x.toDouble()It would not compile until we check if it is not null:
if (x != null) {
val h = x.toDouble()
}️ Protection Operators
When working with variables that can be null, Kotlin forces us to be careful when calling their methods or properties. This is where three key operators come into play.
1. Safe Call Operator (?.)
If we want to be able to use the properties and methods provided by the Kotlin API or generated by third parties or ourselves without fear of getting a null reference exception at any time, we can use the ? character before the property or method name:
var a: String? = "abc"
a = null
a?.length // NULLIn the previous code snippet, if we execute it at the moment of a?.length where the value of variable a is null, it gives us that a?.length is also null, which would not happen if we did not use the ? character before the property name to access (?.length).
Another example:
val x: Int? = null
println(x?.toDouble()) // Prints "null" instead of breaking2. Not-Null Assertion Operator (!!)
There is another operator that we can use similar to the ? used previously, and it is the !! operator which, if the queried variable is null, would return an exception:
var a: String? = "abc"
a = null // bien
a!!.length // NULLPointerExceptionIn summary, the ? operator would return null when accessing some property or method if the variable is null, and the !! operator would return an exception if some property or method of the variable is accessed if it is null.
This operator is used when we are completely sure that the variable is not null. It is the classic approach: if you are wrong and the variable is null, the program will explode with an exception. Use it with caution.
3. Elvis Operator (?:): Returning custom values in null variables
If we want it to return another value that is not null but rather some other defined by us, we can also do the following, whose scheme is very similar to short conditionals in PHP (The Elvis Operator):
val x: Int? = null
val result = x ?: 80 println(result) // Prints 80
val l = b?.length ?: -1Its function is to assign a default value in case the reference is null. It is the ideal middle ground: the application doesn't explode, but it doesn't leave you with an empty null either.
Conclusion
The concept is the same whether for a String, an Int, or any complex object. If you have a variable that could be null, protect yourself using these operators. If you don't want your application to "explode in your face" with an exception or simply show a null, the Elvis Operator is your best ally.
With this, we can now use data types in Kotlin without problems, whether we want to use the new Kotlin scheme that does not allow nulls by default, or the more common one that allows nulls but with the problem of null references; we already know how to handle it to avoid null references when accessing properties or methods. In the next post, we will see how to use methods and classes in Kotlin.
The next step is to learn how to use conditionals in Kotlin: if and when.
I agree to receive announcements of interest about this Blog.
In this post, we'll talk about null and non-null data types as well as unary operators for null data types that allow variable properties to be accessed safely even when the reference is null in Kotlin.