skip to content

How does a nullable Boolean? behave in conditions, and what does the expression `flag == true` accomplish compared to just `flag`?

level: seniorimportance: should knowfreq 45%

answer

  1. Boolean? = true / false / null
  2. Can't use Boolean? directly in if
  3. flag == true folds null into false
  4. flag != true means null OR false
  5. ?: gives an explicit null default; avoid !!

basics

~20 s

A Boolean? can be true, false, or null, so you can't use it directly in an if. Writing flag == true safely treats null as 'not true' (false). It's a common, null-safe way to check a nullable flag.

solid answer

~40 s

A `Boolean?` has three states — true, false, null — so it isn't usable directly as a condition (`if (flag)` fails to compile because the condition must be non-null Boolean). The idiomatic fixes: `flag == true` (null and false both yield false), `flag == false` (null and true yield false), or `flag ?: defaultValue` to pick the null fallback explicitly. Because `==` on Kotlin types is null-safe structural equality, `null == true` is simply `false`, so `flag == true` never throws. The `!!` operator would force non-null but throw on null — avoid it for control flow. This pattern frequently appears with safe-call chains like `user?.isActive == true`, where the whole chain is `Boolean?`. The negation `flag != true` means 'null or false'. Understanding which bucket null falls into is the whole point.

code

kotlin · 7 lines
kotlin
val a: Boolean? = null
println(a == true)   // false
println(a == false)  // false
println(a != true)   // true
println(a ?: false)  // false

val verified = user?.profile?.isVerified == true // safe over the chain

go deeper

for a junior

Recognizes Boolean? can be null and that you compare with == true to check it.

for a middle

Builds the full truth table and uses == true / == false / ?: appropriately.

for a senior

Explains null-safe == semantics, safe-call chains producing Boolean?, and why !! is wrong here.

for a principal

Weighs API design — when to expose Boolean? at all vs defaulting, and readability of == true vs ?: across a codebase.

## The three states of `Boolean?` Kotlin distinguishes `Boolean` (only `true`/`false`) from `Boolean?` (also `null`). Because an `if`/`while` condition must be a **non-null `Boolean`**, you cannot write `if (flag)` when `flag: Boolean?` — it's a compile error. ## Comparing to a literal: `flag == true` Kotlin's `==` is **null-safe structural equality** (it compiles to a null-checking `equals`), so comparing a nullable value to a literal never throws: ```kotlin val flag: Boolean? = null if (flag == true) { } // false branch: null != true if (flag == false) { } // false branch: null != false if (flag != true) { } // TRUE: null and false both satisfy this ``` Truth table for `flag == true`: | flag | flag == true | |-------|--------------| | true | true | | false | false | | null | false | So `flag == true` cleanly means "definitely true", folding `null` in with `false`. Symmetrically `flag == false` means "definitely false". ## Alternative: the Elvis operator `?:` When you want an explicit default, use `?:`: ```kotlin if (flag ?: false) { } // null -> false if (flag ?: true) { } // null -> true (opt-out default) ``` `flag == true` is equivalent to `flag ?: false`; pick whichever reads clearer in context. ## Common real-world shape Safe-call chains produce `Boolean?`: ```kotlin if (user?.profile?.isVerified == true) { ... } ``` Here any `null` link short-circuits the chain to `null`, and `== true` correctly treats that as "not verified". ## What to avoid - `if (flag!!)` — `!!` throws `NullPointerException` on null; using it for ordinary control flow is a bug magnet. - Forgetting that `!flag` doesn't compile on a `Boolean?` (you'd need `flag == false` or `flag != true`). ## Key takeaways - `Boolean?` is tri-state; can't be a condition directly. - `flag == true` = "true only"; `flag == false` = "false only"; both treat null as the other side, null-safely. - `?: default` is the explicit-default alternative; reserve `!!` for genuinely impossible-null cases, not flow control.

  • Why doesn't `if (flag)` compile when flag is Boolean?
    An if condition requires a non-null Boolean; a nullable value could be null, which isn't a valid truth value, so the compiler rejects it.
  • What does `flag != true` evaluate to for each state?
    true for null and for false; false only when flag is true. It means 'not definitely true'.

A Boolean? is a light switch that might also be missing entirely; == true asks 'is it definitely ON?' and treats a missing switch as not-on.

saying these in an interview costs you the question

  • Using !! on a nullable flag for routine control flow
  • Thinking null in a condition is treated as false automatically
  • Believing flag == true can throw on null
  • Confusing flag == false with !flag on a Boolean?
  • Not realizing safe-call chains yield Boolean?

context