Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Null Safety and Safe Calls | Control Flow and Collections
Android Development with Kotlin
course content

Зміст курсу

Android Development with Kotlin

Android Development with Kotlin

1. Kotlin Basics
2. Control Flow and Collections
3. Object-Oriented Programming in Kotlin

book
Null Safety and Safe Calls

In Kotlin, as in any other programming language, there are empty variables or objects. For example, let's say we have a variable "name," and the user has not filled in this field. In this case, the variable will hold the value null.

Null

In programming, null represents a special value that indicates the absence of any value or object. This means that a variable containing null does not reference any object in memory. Null is used to indicate that a variable is either uninitialized or explicitly holds no value.

Null is a common cause of many errors, and in this chapter, we will learn how to work with this emptiness inside variables or objects properly!

Nullable Types and the `?` Operator

In Kotlin, types are non-nullable by default, which means you cannot assign a null value to a variable of a non-nullable type. To declare a variable that can hold a null value, you use the ? operator.

Here’s how it looks in the code:

kt

Main

copy
12345678
fun main() { var nonNullableString: String = "Hello" nonNullableString = null // This would cause a compile-time error var nullableString: String? = "Hello" nullableString = null // This is allowed println(nullableString) }

As you can see, when we run the code, we get an error telling us that we cannot assign null to a non-nullable type String.

However, below that, we define a new variable with the data type String?, which allows us to assign null without any errors. This way, Kotlin helps us control the values of the variables we work with.

So, to make it possible to create variables that can hold null, we need to add the ? symbol to the data type when declaring the variable.

Let's comment out the line that causes the error and look at the result:

kt

Main

copy
12345678
fun main() { var nonNullableString: String = "Hello" //nonNullableString = null // This would cause a compile-time error var nullableString: String? = "Hello" nullableString = null // This is allowed println(nullableString) }

Don't forget to mark variables that can hold a null value with the special symbol in your program!

Safe Calls and the Elvis Operator

You cannot call methods or access certain properties on variables or objects that can hold a null value. For this, there are safe calls, which are also done using the ? symbol.

Let's first look at a situation where we attempt to call the .length property on a string variable that contains a null value.

Note

The length property returns the length of the string, which is the number of characters in the string. For example, the string "Hello" has 5 elements, with each letter/symbol in the word being counted as a separate element.

kt

Main

copy
1234
fun main() { var nullableString: String? = "Hello" println(nullableString.length) }

As you can see, the compiler tells us that we can only use safe calls because you cannot use properties or methods on a variable that MIGHT contain a null value.

Let's call this property using a safe call with the ?. syntax:

kt

Main

copy
1234
fun main() { var nullableString: String? = "Hello" println(nullableString?.length) }

To call a property or method on a variable that might contain null, we use the following syntax:

variableThatMightContainANull?.property

This way, it will be a safe call that will return null if the variable contains null, instead of throwing an error or exception when accessing any property:

kt

Main

copy
12345
fun main() { var nullableString: String? = "Hello" nullableString = null println(nullableString?.length) }

There's also a way to handle a null value using a regular if-else statement.

It will look like this:

kt

Main

copy
12345678910
fun main() { var nullableString: String? = "Hello" nullableString = null if (nullableString != null) { println(nullableString.length) } else { println("nullableString is null") } }

In the code example above, we prevent performing operations on a variable that might be null.

The Elvis Operator

The Elvis operator ?: is used to provide a default value when the expression on the left-hand side is null.

Let's look at a code example where we try to assign the length of a string, which might be null, to a variable:

kt

Main

copy
12345678
fun main() { var nullableString: String? = "Hello" //nullableString = null val length: Int = nullableString?.length ?: 0 println(length) }

In the code above, we try to get the length of a string, but if the value of that string is null, we assign the variable length a value of 0.

When you run the code, you'll see the value 5, which is the length of the string "Hello."

But let's uncomment the line that sets the nullableString variable to null and see the result:

kt

Main

copy
12345678
fun main() { var nullableString: String? = "Hello" nullableString = null val length: Int = nullableString?.length ?: 0 println(length) }

As you can see, instead of null, we get 0, which we specified in the Elvis operator.

Note

When using the Elvis operator, we still need to use the safe call operator; otherwise, the compiler will not allow us to call properties or methods on a variable that might contain null.

Non-Null Assertions

And the last thing we'll look at in this chapter is Non-Null Assertions.

This is used when a variable that MIGHT hold a null value is definitely not null (or you believe it isn't).

Here's how to use such an assertion:

kt

Main

copy
12345678
fun main() { var nullableString: String? = "Hello" //nullableString = null val length: Int = nullableString!!.length println(length) }

If the value is null, it throws a NullPointerException:

kt

Main

copy
12345678
fun main() { var nullableString: String? = "Hello" nullableString = null val length: Int = nullableString!!.length println(length) }

Use the non-null assertion operator with caution, as it can lead to runtime exceptions if the value is actually null.

Summary

Let's summarize briefly:

  • To allow a variable to hold a null value (making it nullable), you need to add a question mark when declaring the type: String?.
  • To use a safe call, you add a question mark after the variable name when attempting to call a method or property: variable?.property.
  • If you want to assign a specific value when the variable is null, you can use the Elvis operator: length = nullableString?.length ?: 0.
  • If you're certain that the variable is not null, you can use a non-null assertion: length = nullableString!!.length, but be cautious as this can lead to many errors!
1. How do you declare a variable in Kotlin that can hold a null value?
2. What does the Elvis operator `?:` do in Kotlin?
How do you declare a variable in Kotlin that can hold a null value?

How do you declare a variable in Kotlin that can hold a null value?

Виберіть правильну відповідь

What does the Elvis operator `?:` do in Kotlin?

What does the Elvis operator ?: do in Kotlin?

Виберіть правильну відповідь

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 7
We're sorry to hear that something went wrong. What happened?
some-alt