Kotlin, Zero to Kotlin Hero

Zero to Kotlin Hero : Say Goodbye to Nulls

The previous article was about Kotlin Android Extensions. In this article, get ready to understand how Kotlin handles nulls and say goodbye to them.

Contrary to the picture below, we don’t love you. You give us multiple headaches 🤷🏼‍♀️.

 

 

The null reference created by Tony Hoare which is also known as his Billion Dollar Mistake has been addressed in the Kotlin type system. Now after interacting with some Kotlin developers recently, I have come to understand that some think that Kotlin has removed the Null Pointer Exception. This is NOT the case.

Null safety doesn’t necessarily mean that nulls don’t exist anymore in Kotlin, it just means that except I say I want to have a nullable variable in my code, I won’t have one.

 

What can cause a Null Pointer Exception?

  • Trying to access a member on a null reference
  • Throwing a Null Pointer Exception
  • Synchronizing over a null object
  • Trying to invoke a method on a null object

 

How does Kotlin handle nulls?

By default, a Kotlin variable cannot have a null value.

var firstname: String = "nenne"  //this works
name = null  // compilation error

The line above would throw an error. To allow nulls (because we want to, not because we don’t have a choice), we have the add ? when declaring variables like so:

var lastname: String? = null  //this would work

 

So how is this safe if I can still declare nullable variables?

Looking at firstname, whenever we access a property or call a method on this variable, we would never have a Null Pointer Exception because firstname cannot hold nulls. It is safe to say:

val fnameLength = firstname.length

But accessing the same property on lastname would cause a compilation error because lastname could be null and we don’t want to get into any trouble.

val lnameLength = lastname.length  //error - variable 'lastname' can be null

 

How do I now call these methods on a nullable variable 🙄?

There are multiple ways to do this in Kotlin; Conditional statements, The Elvis Operator, Safe Calls, The Not Null Assertion Operator.

Conditional statements

This involves explicitly checking for nulls using if statements. If a variable is not null, an action on that variable can be performed (or whatever you want to do depending on your logic). You can also provide a fallback action in case the variable is null. It helps in knowing what state your application is in.

val a = "Adora"
if (a != null) {
   print("$a has ${a.length} characters")
} else {
   print("No values")
}

Note that this only works where a is immutable because otherwise, it might happen that a changes to null after the check and that becomes a problem.

Safe calls

The safe call operator is written as ?..

val s: String? = null
println(s?.length)

This returns the length of the string if the string is not null and returns null otherwise.

The Elvis Operator

This still requires checking for nulls in conditions but going one step further. What actually happens is: Check if a is not null. If a is not null, use it. Otherwise, use a non-null variable b. See the syntax below:

val result: Int = if (a != null) a.length else -1

In shorthand form, it can be written with the Elvis operator ?: like this:

val result = a?.length ?: -1

You can think of the Elvis operator as a mix of conditional statements and safe calls. If the expression to the left of ?: is not null, the Elvis operator returns it. If its null, it returns the expression to the right. The right-hand side expression is evaluated only if the left-hand side is null.

The Not Null Assertion Operator

Personally, I would beg you to stay away from this. But if you like NPEs, then you can use this. The not-null assertion operator (!!) converts any value to a non-null type and throws an exception if the value is null. We can write a!!, and this will return a non-null value of a(e.g., a String in our example) or throw an NPE if a is null:

val a = null
val result = a!!.length  //this would throw an NPE.

This would throw an NPE. If that’s not what you wanted, be careful using this.

 

Conclusion

We have seen how nulls are handled in Kotlin. Get ready to know about Kotlin functions in the next article!

 

 

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *