Learn the Basics of the Kotlin Language

May 22 2024 · Kotlin 1.9, Android 14, Kotlin Playground 1.9

Lesson 05: Learn Null

Demo

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Any attempt to dereference a null value results in a NullPointerException. To better handle null values, Kotlin provides null-safety. These include a number of mechanisms that ensure better handling of null values and prevents common programming issues related to null values. In this demo, you’ll see how Kotlin handles null values. To start, open a new Kotlin Playground session by visiting https://play.kotlinlang.org. In Kotlin, a variable is said to be nullable if it can hold a null value. To initialize a null value, simply assign null to the variable.

fun main() {
   val items = null
}
fun main() {
   val items: Int? = null
}
fun main() {
   val items: Int? = null

   println(items!!)
}
fun main() {
   val items: Int? = null

   try {
      println(items!!)
   } catch(e: NullPointerException) {
      println("NullPointerException safely handled :]")
   }
}

Elvis Operator

You could also check if the value is null before working with it:

fun main() {
   val items: Int? = null
   var amount = 25
   if (items != null){
      amount = items
   }
   println("Amount to pay: $amount")
}
fun main() {
   val items: Int? = null
   var amount = items ?: 25
   println("Amount to pay: $amount")
}
fun main() {
   val apple: Int? = null
   val orange: Int = 5

   val total = apple?.plus(orange)
   println(total)
}
fun main() {
   val apple: Int? = 5
   val orange: Int = 5

   val total = apple?.plus(orange)
   println(total)
}
fun main() {
   val apple: Int? = 5
   val orange: Int = 5

   val total = apple?.let { orange.plus(it) }
   println(total)
}

NotNull Delegate

The delegate pattern is a software design pattern in which an object delegates its duties to another object. The notNull delegate allows a variable to be declared as non-nullable, but not during initialization. It must be a mutable variable since the value has to be provided later on in the program.

import kotlin.properties.Delegates

fun main() {
   var items by Delegates.notNull<Int>()

   items = 5
   println(items)
}

Lateinit Modifier

This modifier is used to initialize a variable later in the program rather than at declaration. It behaves just like Delegate.notNull(). Define and initialize a Book class with a method called display that prints a text:

lateinit var book: Book

fun main(args: Array<String>) {
  book = Book()
  book.display()
}

class Book {
  fun display(){
    println("lateinit modifier works just like Delegate.notNull()")
  }
}
lateinit modifier works just like Delegate.notNull()

The Null Assertion Operator

This operator asserts that an object, though nullable, is not null.

fun main() {
   var fruit: String? = null
   fruit = "Salad"
   println(fruit!!.uppercase())
}

Nullable Receiver

Some functions are defined on nullable receivers. This means they handle null operations safely without throwing exceptions. A good example is the toString() function. If you call toString() on a null object, it returns a “null” string:

fun main() {
   val items = null
   val result = items.toString()
   println(result::class.java.simpleName)
}

Safe Casts

Casting in programming means converting one data type to another data type. You must ensure that you’re casting the object to the correct type. For instance, you cannot cast an integer to a string, but you can cast an object of type Any to a string if it contains a string value.

fun main() {
   val food: Any = "Corn"
   val staple = food as? Int
   println(staple)
}
fun main() {
   val food: Any = "Corn"
   val staple = food as Int
   println(staple)
}
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap')
 at FileKt.main (File.kt:3)
 at FileKt.main (File.kt:-1)
 at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (:-2)

Nullable Collections

When a collection contains nullable data, it’s important to handle it carefully. Rather than manipulating all items in a null-safe manner, it’s recommended to remove all null values from the collection before use. You can do this by using the filterNotNull() method, which is available on all Collection types.

fun main() {
   val fruits = listOf("Pear", "Mango", null, "Orange")
   println(fruits)

   val nonNullFruits = fruits.filterNotNull()
   println(nonNullFruits)
}
See forum comments
Cinema mode Download course materials from Github
Previous: Instruction 3 Next: Conclusion