Skip to content
ArceApps Logo ArceApps
ES

The Billion Dollar Mistake: Null Safety in Kotlin vs Java

⏱️ 3 min read
The Billion Dollar Mistake: Null Safety in Kotlin vs Java

💥 Tony Hoare’s Confession

In 1965, Tony Hoare invented the “Null Reference”. Years later, he apologized, calling it his “Billion Dollar Mistake”. The reason? NullPointerException (NPE). It is the most common error in Java and has caused infinite crashes and financial losses.

🛡️ Kotlin’s Solution: The Type System

In Java, any object reference can be null. In Kotlin, the type system distinguishes between references that can hold null (nullable) and those that cannot (non-null).

Non-Null by Default

var a: String = "abc"
a = null // ❌ Compilation Error

Explicitly Nullable

var b: String? = "abc"
b = null // ✅ OK

This means that if you see a String variable in Kotlin, you have the guarantee that it will never be null. You don’t need to check if (a != null).

🛠️ Operators for Nullable Types

When you have a String?, the compiler forces you to handle the null case.

1. Safe Call (?.)

Executes the action only if it is not null. Otherwise, returns null.

val length: Int? = b?.length

2. Elvis Operator (?:)

“If it is null, use this default value”.

val length: Int = b?.length ?: 0

3. Not-null Assertion (!!)

“I know what I’m doing, trust me (or crash)”. Avoid using this.

val length: Int = b!!.length // 💥 Throws NPE if b is null

🔄 Interoperability with Java

When Kotlin calls Java code, it doesn’t know if a variable can be null (unless it is annotated with @Nullable or @NonNull). Kotlin treats these types as Platform Types (String!).

Best Practice: When overriding a Java method in Kotlin, explicitly define nullability.

// Java
public String getName();
// Kotlin Override
override fun getName(): String? // Safer to assume it can be null

🧠 Null Object Pattern

Sometimes, instead of returning null, it is better to return a valid but empty object.

interface User {
    val name: String

    // Pattern
    object Anonymous : User {
        override val name = "Guest"
    }
}

// Usage
val currentUser: User = repository.getUser() ?: User.Anonymous

🎯 Conclusion

Kotlin doesn’t eliminate null (it’s useful for representing “absence of value”). What Kotlin eliminates is the surprise of null. By making nullability explicit in the type system, you catch 90% of bugs at compile time, before the app reaches the user.

You might also be interested in

Mastering Kotlin Scope Functions: let, run, with, apply, also
Kotlin September 15, 2025

Mastering Kotlin Scope Functions: let, run, with, apply, also

let, run, with, apply, also... Which one to use and why? A deep dive into Kotlin Scope Functions, language design theory, and best practices.

Read more
Null Safety in Kotlin: The End of the 'One Billion Dollar Mistake'
Kotlin September 10, 2025

Null Safety in Kotlin: The End of the 'One Billion Dollar Mistake'

Deeply understand Kotlin's type system, how it eliminates NullPointerExceptions, and advanced techniques for handling nullability elegantly.

Read more
Kotlin Delegation: Clean Code Pattern
Kotlin October 15, 2025

Kotlin Delegation: Clean Code Pattern

Master the Delegation pattern in Kotlin. Use `by` keyword to replace inheritance with composition. Practical examples for Android.

Read more