Kotlin Null Safety – Kotlin Nullable

Filed Under: Kotlin

In this tutorial, we’ll look into Kotlin Null Safety. NullPointerException is one of the most common type of bugs any programmer witnesses in their projects. Let’s see how Kotlin deals with it.

Kotlin Null Safety

Kotlin null safety
Kotlin compiler by default doesn’t allow any types to have a value of null at compile-time.
For Kotlin, Nullability is a type. At a higher level, a Kotlin type fits in either of the two.

  • Nullability Type
  • Non-Nullability Type

Nullability as a Type

We can’t define the following syntax in Kotlin.


var str: String = "JournalDev Kotlin Archives"
str= null //compilation error

var a : String = null // compilation error.

To set a type as Nullable we need to append a ? to the type as shown below.


var a : String? = null
var newStr : String? = "Kotlin Null Safety"
newStr = null

Now whenever we access a Nullable Referernce, we need to handle the null cases carefully.
Note: Adding a ? changes the type of a variable from String to String?, Int to Int? and so on.
The most common way is using the if else statements as seen below.


if(a!=null)
{
print("The value of a is $a")
}
else{
print("Sorry a is null")
}

Now the above approach can lead to plenty of if else nested brackets. Kotlin does provide a simpler way to access nullable references using Safe Calls.

Safe Calls

To call a function or a property over a variable, we typically do the following thing.


var a : String = "Hello"
print(a.length)

This WON’T always work with Nullable References.


var a : String? = "Hi"
print(a.length) //prints 2

a = null
print(a.length) // compilation error

The dot reference can’t be used when the Nullable reference holds a null value.
Hence, Kotlin provides us with a safe call operator to use over Nullable References as shown below.


a = "Hi"
print(a?.length) //prints 2

a = null
print(a?.length) //prints null

The safe call ?. executes the relevant call only when the value is non-null.
Else it prints a null for you.

Safe calls are handy when you need to keep nullability checkers over multiple variables as shown below.


var streetName : String? = address?.locality?.street?.addressLine1

There’s another way to call properties on a nullable reference.

!! Operator

Contrary to the safe calls, the !!, also known as the not-null assertion, converts the nullable reference into its non-nullable type irrespective of whether it’s a null or not. This should be used only when you’re certain that the value is NOT NULL. Else it’ll lead to an NPE exception.


a = null
println(a!!.length) // runtime error.

a = "Hi"
print(a!!.length) //prints 2

Safe Casting

The ? operator can be used for preventing ClassCastException as well(another commonly seen exception).


var b : String ="2"
var x : Int? =  b as? Int
println(x) //prints null

In the above code, we’re safe cast the variable b using

as?

. If the cast isn’t successful, the value is set to null thereby preventing ClassCastException.
Another example:


var array1 : Array<Any?> =  arrayOf("1","2","3")
var i : Int? = array1[0] as? Int
println(i) //prints null
var s : String? = array1[0] as? String
print(s) //prints 1

Elvis Operator

Up until now, whenever the safe call operator returns a null value, we don’t perform an action and print null instead. The Elvis operator ?: allows us to set a default value instead of the null as shown below.


var newString : String?  = "JournalDev.com"
println(newString?.length) //prints 14
newString = null
println(newString?.length?:"-1") //prints -1

The elvis operator is equivalent to the following:


if(newString!null)
{
print(newString.length)
}
else{
print("-1")
}

Another sample:


var streetName : String? = address?.locality?.street?.addressLine1 ?: "Street Name not found"

Using let()

Let function executes the lamda function specified only when the reference is non-nullable as shown below.


newString = " Kotlin from Android"
newString?.let { println("The string value is: $it") }
newString = null
newString?.let { println("The string value is: $it") }

The statement inside let is a lamda expression. It’s only run when the value of newString is not null.
it contains the non-null value of newString

Using also()

also behaves the same way as let except that it’s generally used to log the values. It can’t assign the value of it to another variable.
Here’s an example of let and also changed together.


var c = "Hello"

newString = " Kotlin from Android"
newString?.let { c = it }.also { println("Logging the value: $it") }

Note: The statement present inside let can’t be placed in also. Vice-versa can work though.

Filtering Out Null Values

We can filter out Null Values from a collection type using the following function:


var array2: Array<Any?> = arrayOf("1", "2", "3", null)
var newArray = array2.filterNotNull()
println(newArray.size) //prints 3

Java Interoperability

Since Java doesn’t force you to state type as Nullable or Non-Nullable type, Kotlin compiler doesn’t give an error for the following:


var javaObject = MyClass(null)

If you set the Java Annotation @Nullable or @NotNull, the Kotlin compiler would consider them as Nullable or Not Nullable References.
Remember : Nullable references require a ? in Kotlin.

Project Structure

The Kotlin Project below contains various sub-topics we’ve covered in Kotlin till now.
kotlin intellij tutorials

That’s all we’ve got in Kotlin Null Safety. You can download the IntelliJ project that contains the various code snippets we’ve covered in Kotlin so far. Play around with it!

References : Official Docs

Leave a Reply

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

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages