Sling Academy
Home/Kotlin/Kotlin: Can't Use `!!` on Nullable Variable

Kotlin: Can't Use `!!` on Nullable Variable

Last updated: December 01, 2024

Kotlin, known for its modern features and null safety, often puzzles beginners with its approach to handling null values. One dilemma they frequently encounter is trying to use the !! operator on nullable variables. In this article, we will explore how Kotlin deals with nullability, why the !! operator might not be your best friend, and practical ways to handle nulls safely.

Understanding Nullability in Kotlin

Kotlin differentiates between nullable and non-nullable types, guarding against null pointer exceptions (NPE), a common source of frustration in many languages such as Java. In Kotlin, if a variable is declared as a non-null type, it cannot hold a null value. However, if it is declared as a nullable type — defined with a question mark (?) — it can hold null.


var nonNullable: String = "Hello, World!"
var nullable: String? = null

In the snippet above, nonNullable cannot be assigned null, whereas nullable can.

The Danger of the !! Operator

The !! operator is sometimes called the "not-null assertion operator". It promises the compiler that the variable is not null and can be treated as a non-nullable type. If the variable is null, using !! will throw a NullPointerException.


fun lengthOfText(text: String?): Int {
    return text!!.length // Throws NullPointerException if text is null
}

// Usage
val length = lengthOfText(null) // Throws an error

As evident, while !! can sometimes be useful, it should be used cautiously. It can negate the safety benefits that Kotlin provides.

Safer Alternatives to !!

Thankfully, Kotlin offers several safer alternatives to handle nullable values without risking NPEs.

1. Safe Call Operator (?.)

This operator allows you to access a property or call a function on a nullable object. If the object is null, it will return null instead of throwing an exception.


fun lengthOfText(text: String?): Int? {
    return text?.length
}

// Usage
val length = lengthOfText(null) // Returns null
val safeLength = lengthOfText("Kotlin") // Returns the length of "Kotlin"

Here, ?.length safely checks if text is null before attempting to access its length.

2. Elvis Operator (?:)

Named after the resemblance to a sideways emoticon for Elvis Presley’s style, this operator allows you to specify a default value when a nullable variable is indeed null.


fun lengthOfTextWithDefault(text: String?): Int {
    return text?.length ?: 0
}

// Usage
val defaultLength = lengthOfTextWithDefault(null) // Returns 0
val lengthWithDefault = lengthOfTextWithDefault("Kotlin") // Returns length of "Kotlin"

In this example, ?: 0 returns 0 when text is null.

3. Safe Cast Operator (as?)

Kotlin provides a safe cast operator that will attempt to perform a cast if possible or, if not, return null instead of throwing an exception.


val anyValue: Any = "Kotlin"
val text: String? = anyValue as? String // Safe cast

// Safe Cast with Null
val anotherValue: Any = 1234
val anotherText: String? = anotherValue as? String // Returns null

As shown, you can avoid runtime errors by using as? which gracefully returns null in case of a failed cast.

Conclusion

While the !! operator may seem like an easy fix, its usage can introduce errors if not carefully managed. Employing Kotlin's built-in safety mechanisms like the safe call operator, Elvis operator, and safe cast operator can help you effectively manage nullability without sacrificing the reliability of your code.

Next Article: Kotlin: This Cast Can Never Succeed

Previous Article: Kotlin: Lateinit Property Not Initialized

Series: Common Errors in Kotlin and How to Fix Them

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
  • When to Avoid the Null Assertion 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