Kotlin: 'null' does not equal 'true', but also not 'false'

alxgrk

Alexander Girke

Posted on September 21, 2020

Kotlin: 'null' does not equal 'true', but also not 'false'

TL;DR Kotlin has the === operator for referential integrity and none of true, false or null references the same thing. Don't forget that, when comparing nullable booleans.

Today I stumbled upon a hint from IntelliJ. I wanted to write something like the following:

val potentiallyNull: Any? = null // in real world, we wouldn't know whether it's null or not
if (potentiallyNull?.equals("foo") ?: false) {
    println("not printed when null")
}
Enter fullscreen mode Exit fullscreen mode

In words: if potentiallyNull is not null, check for equality with "foo"; otherwise return false.

So, IntelliJ kindly told me: Equality check should be used instead of elvis for nullable boolean check

I thought to myself, alright then, let's apply that nice hint.

What I got was:

if (potentiallyNull?.equals("foo") == true) {
    println("not printed when null")
}
Enter fullscreen mode Exit fullscreen mode

However, later on, I wanted to invert the condition. So naively, I simply replaced true by false:

if (potentiallyNull?.equals("foo") == false) {
    println("print also when null")
}
Enter fullscreen mode Exit fullscreen mode

Unfortunately, the result was not as expected. There was not a single character printed to the console. What went wrong?

Actually, it's quite obvious, but it took me a moment to realize: of course, null is neither the same as true nor as false.

So, I took a step back and rewrote my original condition:

if (potentiallyNull?.equals("foo") ?: true) {
    println("print also when null")
}
Enter fullscreen mode Exit fullscreen mode

IntelliJ again told me to change that and use the equality check, so what I got now was:

if (potentiallyNull?.equals("foo") != false) {
    println("print also when null")
}
Enter fullscreen mode Exit fullscreen mode

The first thing I thought was: How is ... != false different to ... == true?

But again, null is neither the same as true nor as false. So the comparison has actually three possible results: true, false or none of them.

... != false in this case means true or none of them, whereas ... != true means only true.

For more on equality in Kotlin, I recommend to read the official docs on equality

All in all, that wasn't my most brilliant moment for sure, but I thought others might stumble upon that as well. Hope you liked it.

💖 💪 🙅 🚩
alxgrk
Alexander Girke

Posted on September 21, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related