Kotlin Non-Null Assertion

The non-null assertion operator !! tells Kotlin: "I know this value is not null — trust me." It converts a nullable type to a non-nullable type. If the value actually is null at runtime, Kotlin throws a NullPointerException.

How !! Works

val name: String? = "Alice"

val length = name!!.length   // treat name as non-null, access .length
println(length)              // 6

name!! 
  │
  └── Is name null?
       │
       ├── NO  → unwrap and use as String → access .length → OK
       └── YES → throw NullPointerException immediately

What Happens When It Is Null

val value: String? = null

val result = value!!.uppercase()
// Throws: NullPointerException: value!! cannot be null

When to Use !!

Use !! only when you are absolutely certain the value is not null and the type system does not recognize it yet — for example, when working with Java interop or platform types. In pure Kotlin code, prefer safe calls (?.) or Elvis (?:) instead.


┌─────────────────────────────────────────────────────┐
│  !! is appropriate when:                            │
│  - You are calling Java code that returns nullable  │
│    but you know it never returns null at that point │
│  - You have already validated the value elsewhere   │
│    but the type system cannot see that validation   │
│                                                     │
│  !! is NOT appropriate when:                        │
│  - You are just being lazy about null handling      │
│  - You are unsure whether the value is null         │
│  - A safe call or Elvis can do the job              │
└─────────────────────────────────────────────────────┘

Safe Alternatives

val email: String? = getEmailFromServer()

// Risky — crashes if null
val domain = email!!.substringAfter("@")

// Safe — returns null if email is null
val domain = email?.substringAfter("@")

// Safe with fallback
val domain = email?.substringAfter("@") ?: "unknown.com"

!! vs Safe Call Comparison


Scenario          │ ?.           │ !!
──────────────────┼──────────────┼──────────────────────
Value is not null │ works fine   │ works fine
Value is null     │ returns null │ throws NullPointerException
Error at          │ never        │ runtime
Recommended?      │ yes          │ only when certain

Platform Types (Java Interop)

When Kotlin calls Java code, the return type may be a platform type (neither nullable nor non-nullable). In this case, Kotlin cannot enforce null safety, and !! is sometimes needed:

// Java method: public String getUserName() { return null; }

val name = javaClass.getUserName()!!.uppercase()
// crashes if getUserName() returns null — use carefully

Practical Example: Config Loader

fun loadConfig(key: String): String? {
    val config = mapOf("db_host" to "localhost", "db_port" to "5432")
    return config[key]
}

fun main() {
    // We know "db_host" exists in config, so !! is acceptable here
    val host = loadConfig("db_host")!!
    println("Connecting to: $host")

    // Safer version with fallback
    val port = loadConfig("db_port") ?: "3306"
    println("Port: $port")

    // This will crash — "timeout" key does not exist
    // val timeout = loadConfig("timeout")!!
}

Output:

Connecting to: localhost
Port: 5432

The key rule: use !! sparingly. Every !! in your code is a potential crash waiting to happen if your assumption about the value ever turns out to be wrong.

Leave a Comment

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