Sitemap

Level Up Coding

Coding tutorials and news. The developer homepage gitconnected.com && skilled.dev && levelup.dev

Avoid Using !! in Kotlin — Safer Alternatives for Null Handling

4 min readOct 9, 2025

--

Press enter or click to view image in full size

Not a Medium member? Read this story for free here — valid for 30 days.

Null-safety is one of Kotlin’s main advantages over Java. The type system forces developers to think about possible nullvalues and handle them explicitly. However, Kotlin also provides the not-null assertion operator !!, which can convert any nullable value into a non-null type. If the value is actually null, it throws a NullPointerException.

At first, !! may look like a convenient shortcut when you are confident that a value cannot be null. But this is a fragile assumption. As code evolves, what was once guaranteed may no longer hold. The operator stays in place, and the result is an unexpected crash in production.

This article explains why you should avoid !! and shows safe and maintainable alternatives that cover most real-world cases.

Why !! Is a Risk for Your Kotlin Code

The !! operator effectively bypasses Kotlin’s type system. It silences compiler warnings by saying “I know better than the compiler.” But if that assumption is wrong, the app will crash with a NullPointerException.

Example:

val user: User? = getUser()
val name: String = user!!.name

If getUser() ever returns null, or if user.name is null, the app crashes immediately. This kind of bug is often found late, under conditions that are hard to reproduce.

Safer alternatives exist for every situation where !! might be tempting.

Alternative 1: Safe Call with Fallback: ?., orEmpty(), and Elvis ?:

The safe call operator ?. allows you to access a property or method only when the object is not null. Combined with fallback logic, it eliminates the need for !!.

Example with String?:

val user: User? = getUser()
val userName: String = user?.name.orEmpty()

If either user or name is null, the result is an empty string. The final type is non-null String.

Example with other types:

val user: User? = getUser()
val age: Int = user?.age ?: 0

Here ?: (Elvis operator) provides a default value when user is null.

When to use:

  • You need a non-null result.
  • A default value makes sense in case of null.
  • You want concise and safe code.

Alternative 2: Explicit Null Check with if

Sometimes a default value is not enough. In such cases, use an explicit if check.

val user: User? = getUser()
if (user != null) {
val name: String = user.name
println(name)
}

This makes the null handling explicit and readable. It avoids surprises and makes it clear what happens when the value is null.

When to use:

  • Business logic must branch depending on nullability.
  • You want full control over both null and non-null cases.

Alternative 3: Fail Fast with requireNotNull and Custom Messages

When a value must not be null, use requireNotNull. Unlike !!, it allows you to specify a clear failure message.

val user: User? = getUser()
val name: String = requireNotNull(user?.name) { "User name is required for this operation" }

If user or name is null, the code throws IllegalArgumentException with the provided message. This is much more informative than a generic NullPointerException.

Best practice:
Use requireNotNull only in cases where null truly indicates a programming error (for example, invalid state or incorrect API usage). This way, crashes include meaningful diagnostic information.

Alternative 4: Concise Null-Safe Blocks with let

The let function is a safe way to execute logic only when a value is not null.

val user: User? = getUser()
user?.let {
println("User name: ${it.name}")
}

Inside the let block, it is guaranteed to be non-null. This avoids boilerplate null checks and keeps code clean.

When to use:

  • You want to perform an action only when the value is non-null.
  • The alternative would be a simple if (x != null) check.

Key Takeaways: Writing Safer Kotlin Code Without !!

Using !! in Kotlin is a form of blind trust. It disables the type system’s safety guarantees and introduces potential crashes. Safer alternatives exist for every use case:

  • Use ?. with orEmpty() or Elvis ?: for fallback values.
  • Use explicit if checks when business logic depends on nullability.
  • Use requireNotNull for programmer errors, with a clear failure message.
  • Use let for concise null-safe blocks.

As a rule of thumb, prefer explicit handling over shortcuts. This makes your code safer, clearer, and easier to maintain in growing projects.

Stay updated: follow me on Medium for new Kotlin and Android articles, examples, and checklists.

Press enter or click to view image in full size

Anatolii Frolov
Senior Android Developer
Writing honest, real-world Kotlin & Jetpack Compose insights.
📬 Follow me on Medium

--

--

Level Up Coding
Level Up Coding
Anatolii Frolov
Anatolii Frolov

Written by Anatolii Frolov

Android & Kotlin insights — practical tips, interview prep, no fluff.

Responses (5)

Thanks for sharing, Anatolii. I'll also add my thoughts on the filterNotNull and mapNotNull operators, which are applicable when working with collections

--

Thanks for sharing, Anatolii.

--

Thanks for article. Simple and clear

--