Question

How to Null Check in Kotlin: == vs === Explained

kotlinkotlin-null-safety

Question

In Kotlin, what is the correct way to check whether a value is null?

For example, should I write:

if (a === null) {
    // do something
}

or:

if (a == null) {
    // do something
}

And for checking that a value is not null, should I use:

if (a !== null) {
    // do something
}

or:

if (a != null) {
    // do something
}

I want to understand which form is preferred in Kotlin and why.

Short Answer

By the end of this page, you will understand how Kotlin handles null checks, the difference between == and ===, and why a == null and a != null are the usual choices. You will also learn when referential equality with === matters and how null checks fit into everyday Kotlin code.

Concept

In Kotlin, null checking is closely tied to equality operators.

Kotlin has two main kinds of equality:

  • == → structural equality
  • === → referential equality

Structural equality: ==

== checks whether two values are considered equal. In Kotlin, this is translated safely and works well with null.

For example:

a == null

means: "Is a equal to null?"

This is the standard and preferred way to check for null in Kotlin.

Likewise:

a != null

is the standard way to check that a value is not null.

Referential equality: ===

=== checks whether two references point to the exact same object in memory.

For most null checks, you do not use === or !==. Even though a === null works, it is not the idiomatic style for general null checking.

Why == null is preferred

Kotlin is designed so that == handles equality safely, including null. This makes code:

  • easier to read
  • consistent with Kotlin style
  • idiomatic in most codebases

Recommended forms

Use these in normal Kotlin code:

if (a == null) {
    // a is null
}

if (a != null) {
    // a is not null
}

These are clear, conventional, and what most Kotlin developers expect to see.

Mental Model

Think of Kotlin equality like comparing people in two different ways.

  • == asks: Do these two look the same or represent the same value?
  • === asks: Are these literally the exact same person standing here?

Now think about null as "nobody is there."

If you want to check whether a spot is empty, you usually just ask:

  • a == null → "Is nobody there?"

You do not need the stricter identity-style question for normal null checks.

So:

  • == null = the normal empty-check
  • != null = the normal not-empty-check
  • === = special identity comparison, used for object reference questions, not everyday null checks
Take Quiz

Syntax and Examples

The usual Kotlin syntax for null checking is:

if (value == null) {
    // handle null
}

if (value != null) {
    // safe to use value in this block
}

Example 1: Basic null check

fun printName(name: String?) {
    if (name == null) {
        println("No name provided")
    } else {
        println("Name: $name")
    }
}

Here, name is nullable because its type is String?.

  • If name is null, the first branch runs.
  • Otherwise, Kotlin knows name is not null inside the else block.

Example 2: Not-null check

fun greet(name: String?) {
    if (name != null) {
        println("Hello, $name")
    }
}

Inside the if block, Kotlin smart-casts name to a non-null String.

Example 3: === exists, but is not the usual choice

fun check(value: String?) {
    if (value === null) {
        println("Value is null")
    }
}

This works, but most Kotlin code uses value == null instead because it is the idiomatic form for null checking.

Key takeaway

For null checks, prefer:

value == null
value != null

Step by Step Execution

Consider this example:

fun showLength(text: String?) {
    if (text != null) {
        println(text.length)
    } else {
        println("Text is null")
    }
}

Now call it like this:

showLength("Kotlin")
showLength(null)

First call: showLength("Kotlin")

  1. text receives the value "Kotlin".
  2. Kotlin evaluates text != null.
  3. Since text is not null, the condition is true.
  4. The first block runs.
  5. Kotlin smart-casts text from String? to String inside that block.
  6. text.length is printed, which is 6.

Second call: showLength(null)

  1. text receives null.
  2. Kotlin evaluates text != null.
  3. Since text is null, the condition is false.
  4. The else block runs.
  5. Text is null is printed.

What this shows

A normal null check with != null does two useful things:

  • it tests whether the value exists
  • it lets Kotlin safely treat the value as non-null inside the matching block

Real World Use Cases

Null checks are everywhere in Kotlin applications because many values may be optional or missing.

API responses

A server may return optional fields:

data class User(val nickname: String?)

fun printNickname(user: User) {
    if (user.nickname != null) {
        println(user.nickname)
    } else {
        println("No nickname")
    }
}

Form input validation

A field may be blank or absent:

fun validateEmail(email: String?) {
    if (email == null) {
        println("Email is required")
    }
}

Database values

Columns can contain null:

fun processMiddleName(middleName: String?) {
    if (middleName != null) {
        println(middleName.uppercase())
    }
}

Android or backend configuration

Configuration entries may be optional:

fun loadPort(port: Int?) {
    if (port == null) {
        println("Using default port")
    }
}

In all of these cases, == null and != null are the normal tools.

Take Quiz

Real Codebase Usage

In real Kotlin projects, null checks are often combined with Kotlin features that reduce boilerplate.

Guard clauses

Developers often return early when a required value is missing:

fun sendEmail(address: String?) {
    if (address == null) return
    println("Sending email to $address")
}

Validation before processing

fun saveUsername(username: String?) {
    if (username == null) {
        throw IllegalArgumentException("Username cannot be null")
    }
    println("Saving $username")
}

Smart casts after != null

fun printUppercase(value: String?) {
    if (value != null) {
        println(value.uppercase())
    }
}

Prefer Kotlin null-safety tools when possible

Often, developers avoid explicit null checks by using:

  • safe call: ?.
  • Elvis operator: ?:
  • let

Example:

fun printLength(text: String?) {
    println(text?.length ?: 0)
}

Team style and readability

Even though === null can work, most Kotlin codebases prefer == null because:

  • it matches common Kotlin style
  • it is easier for readers to scan
  • it communicates intent clearly: this is a null check, not an identity comparison

Common Mistakes

Mistake 1: Using === for everyday null checks

if (a === null) {
    // works, but not idiomatic
}

This is valid, but it suggests referential comparison when a normal null check is all you need.

Prefer:

if (a == null) {
    // idiomatic Kotlin
}

Mistake 2: Confusing == and ===

Beginners often think:

  • == is "double equals"
  • === is "extra strict equals"

But in Kotlin, the difference is not about being stricter in general. It is about value equality vs reference identity.

val a = "hi"
val b = "hi"

println(a == b)   // true: same value
println(a === b)  // may be true or false depending on reference identity

Mistake 3: Forcing non-null with !!

Broken approach:

fun printLength(text: String?) {
    println(text!!.length)
}

If text is null, this throws an exception.

Safer approach:

fun printLength(text: String?) {
    if (text != null) {
        println(text.length)
    }
}

Mistake 4: Forgetting that nullable types need handling

Broken code:

fun greet(name: String?) {
    println(name.length)
}

This does not compile because name may be null.

Correct version:

fun greet(name: String?) {
    if (name != null) {
        println(name.length)
    }
}

Mistake 5: Writing extra-complex null checks

Unnecessarily complex:

if (!(a === null)) {
    println(a)
}

Clearer:

if (a != null) {
    println(a)
}

Comparisons

OperatorMeaningTypical useRecommended for null check?
==Structural equalityCompare valuesYes
!=Structural inequalityCheck values are differentYes
===Referential equalityCheck same object/referenceUsually no
!==Referential inequalityCheck different referencesUsually no

== null vs === null

ExpressionWorks?Idiomatic?Notes
a == nullYesYesPreferred for normal null checks
a === nullYesUsually noUses referential equality style
a != nullYesYesPreferred for not-null checks
a !== nullYesUsually noRarely needed for null checks

== vs === with objects

data class User(val name: String)

val u1 = User("Ana")
val u2 = User("Ana")
val u3 = u1

println(u1 == u2)   // true: same content
println(u1 === u2)  // false: different objects
println(u1 === u3)  // true: same object

This is why === is about identity, not everyday equality.

Take Quiz

Cheat Sheet

Preferred null checks

value == null
value != null

Equality operators in Kotlin

==   // structural equality
!=   // structural inequality
===  // referential equality
!==  // referential inequality

Rules of thumb

  • Use == null to check for null
  • Use != null to check for not null
  • Use === only when you truly care about object identity
  • After if (value != null), Kotlin can often smart-cast value

Example

fun example(text: String?) {
    if (text != null) {
        println(text.length)
    }
}

Related null-safety tools

text?.length      // safe call
text ?: "default" // Elvis operator
text!!.length     // unsafe, may throw

Best practice

For normal Kotlin code, prefer:

if (a == null) { ... }
if (a != null) { ... }

FAQ

Should I use == null or === null in Kotlin?

Use == null in normal Kotlin code. It is the idiomatic and preferred way to check for null.

Is a === null wrong in Kotlin?

No, it is not wrong. It works, but it is not the usual style for null checks.

What is the difference between == and === in Kotlin?

== checks value equality. === checks whether two references point to the exact same object.

Should I use != null or !== null?

Use != null for standard not-null checks.

Why does Kotlin allow both forms for null?

Because null can still be compared using either equality model, but Kotlin style strongly favors == and != for normal null checking.

Does if (value != null) make the value non-null inside the block?

Yes, in many cases Kotlin smart-casts the value so you can use it as non-null inside that block.

When should I use === in Kotlin?

Use it when you need to know whether two references are literally the same object, not just equal in value.

Take Quiz

Mini Project

Description

Build a small Kotlin utility that prints information about an optional username. This project helps you practice idiomatic null checking with == null and != null, and shows how Kotlin smart casts work in real code.

Goal

Create a function that safely handles a nullable username and prints different messages depending on whether the value exists.

Requirements

  • Create a function that accepts a nullable String.
  • Print a fallback message when the value is null.
  • Print the username and its length when the value is not null.
  • Use == null or != null for the checks.
  • Call the function with both a real string and null.
Take Quiz

Keep learning

Related questions

View more