Sling Academy
Home/Kotlin/When to Avoid the Null Assertion Operator (`!!`) in Kotlin

When to Avoid the Null Assertion Operator (`!!`) in Kotlin

Last updated: December 05, 2024

Kotlin is a modern programming language that runs on the Java Virtual Machine (JVM) and has grown rapidly in popularity due to its clear syntax and expressive features. One of its noted capabilities is handling nullability directly in the type system, which aims to eliminate the infamous NullPointerException errors. A powerful feature that comes with this null-safety is the null assertion operator, denoted by !!. Despite its convenience, there are instances where using it can be risky and should be avoided. Let's explore why and when you should consider alternatives.

Understanding the Null Assertion Operator

The null assertion operator is used in Kotlin to forcefully assert that a value should not be null. When you append !! after a variable, you're telling the Kotlin compiler that this particular value must not be null, and if it is null, a NullPointerException will be thrown at runtime.

val nullableString: String? = getNullableString()
val nonNullString: String = nullableString!!

In the snippet above, getNullableString might return a null value. If it does and you use !!, your application will crash with a NullPointerException.

When to Avoid

1. Lack of Confidence in Argument Non-nullability

If you're not certain that a variable will never be null, avoid using !!. It's better to use safe calls ?. or the Elvis operator ?: that provide a way to define default behaviors or actions when dealing with nulls.

val length: Int? = nullableString?.length
val safeString: String = nullableString ?: "Default String"

2. When Working with Third-party APIs

When you are consuming APIs or data structures outside of your control or codebase, using !! can be risky as you rely on external operational behavior, which might lead to unpredictable results.

// Assume fetchData can return null
val data: String? = externalService.fetchData()
val processedData: String = data!! // Risky since fetchData might return null!

3. Inside Loops and High-frequency Scenarios

Repeatedly asserting nullability inside loops or high-frequency methods can build up a risk of consistent crashing if your assumption is incorrect. Instead, consider pre-checking conditions or using constructs like let or run.

val listOfStrings: List = listOf("kotlin", null, "java")
for (item in listOfStrings) {
    // Unsafe
    println(item!!.length)
    
    // Safer with let
    item?.let {
        println(it.length)
    }
}

Better Alternatives

1. Safe Call Operator

Use ?. whenever you need to call methods or access properties on a potentially null object, which gracefully skips the operation if the object is indeed null.

val length: Int? = nullableString?.length

2. Null Coalescing with `?:`

The Elvis operator ?: offers a clean way to handle cases where a value might be null, allowing you to specify a default result as a fallback.

val nonNullString: String = nullableString ?: "default"
println(nonNullString.length)

Conclusion

The null assertion operator is a powerful feature in Kotlin but should be used sparingly and with great caution. Understanding and respecting its implications helps write safer, more predictable code. Prefer alternative language features for handling nullability, such as safe calls, let blocks, and the Elvis operator, to maintain robust applications without unexpected crashes.

Next Article: How to Check for Null Values with `if` Statements in Kotlin

Previous Article: Using Null Assertions (`!!`) in Kotlin

Series: Null Safety in Kotlin

Kotlin

You May Also Like

  • How to Use Modulo for Cyclic Arithmetic in Kotlin
  • Kotlin: Infinite Loop Detected in Code
  • Fixing Kotlin Error: Index Out of Bounds in List Access
  • Setting Up JDBC in a Kotlin Application
  • Creating a File Explorer App with Kotlin
  • How to Work with APIs in Kotlin
  • What is the `when` Expression in Kotlin?
  • Writing a Script to Rename Multiple Files Programmatically in Kotlin
  • Using Safe Calls (`?.`) to Avoid NullPointerExceptions in Kotlin
  • Chaining Safe Calls for Complex Operations in Kotlin
  • Using the Elvis Operator for Default Values in Kotlin
  • Combining Safe Calls and the Elvis Operator in Kotlin
  • How to Check for Null Values with `if` Statements in Kotlin
  • Using `let` with Nullable Variables for Scoped Operations in Kotlin
  • Kotlin: How to Handle Nulls in Function Parameters
  • Returning Nullable Values from Functions in Kotlin
  • Safely Accessing Properties of Nullable Objects in Kotlin
  • How to Use `is` for Nullable Type Checking in Kotlin
  • Combining Safe Calls with Collections in Kotlin