How does Kotlin's Nothing type map to the JVM and to Java interop, and what does it mean that it has 'no Java equivalent of its bottom-type semantics'?
answer
- Nothing = bottom type, no instances, subtype of all
- Means 'never returns normally' (throw/loop)
- Return position ⇒ compiles to void
- Drives flow analysis: throw is Nothing, fits any type via Elvis
- Java sees plain void — bottom-type semantics erased
basics
~20 sNothing means a function never returns normally (it throws or loops forever). On the JVM there's no such type, so it usually compiles to void or null, and Java can't see the 'never returns' guarantee.
solid answer
~40 s`Nothing` is Kotlin's **bottom type**: it has no values and is a subtype of every type. A function declared to return `Nothing` never returns normally — it always throws or never terminates. The JVM has no bottom type. In **return position** a `Nothing`-returning function compiles to a `void` method (the call site can't continue anyway). When `Nothing` appears as a **type argument or nullable value type** (e.g. `Nothing?` for a `null` literal's type), it erases toward `void`/`Object`/`null`. Java loses the key compile-time semantics: Kotlin uses `Nothing` return to drive **exhaustiveness and unreachable-code analysis** (e.g. `val x = if (c) a else fail()` type-checks because `fail(): Nothing`), but Java sees only a void method and gets no such guarantees.
code
kotlin · 7 linesfun fail(msg: String): Nothing = throw IllegalArgumentException(msg)
fun lengthOf(s: String?): Int {
val nonNull = s ?: fail("null!") // Nothing <: String, so nonNull: String
return nonNull.length // unreachable analysis: no 'return after fail' needed
}
// From Java: void fail(String) — Java gets no 'never returns' guarantee.go deeper
Knows Nothing means a function never returns normally (throws/loops).
Explains bottom-type semantics, the throw/Elvis type-checking trick, and the void mapping.
Articulates that flow/exhaustiveness analysis is compile-time-only and fully erased at the Java boundary, plus generic erasure of Nothing.
Discusses why a bottom type is fundamentally unrepresentable on the JVM and the trade-offs of encoding it as void plus compiler metadata.
## What `Nothing` is `Nothing` is the **bottom type** in Kotlin's type system: a type with **zero instances** that is a **subtype of every other type**. Because no value can ever exist, an expression of type `Nothing` signals **control flow that never completes normally** — it throws, calls `exitProcess`, or loops forever. Standard library `TODO()` and `error()` return `Nothing`. ## What the compiler does with it The Kotlin compiler uses `Nothing` for **flow analysis**: - A function returning `Nothing` makes the code after a call to it **unreachable** (no "missing return" error there). - It lets expressions type-check: `val s: String = name ?: throw IllegalArgumentException()` works because `throw` has type `Nothing`, which is a subtype of `String`. - `null`'s natural literal type is `Nothing?`. ```kotlin fun fail(msg: String): Nothing = throw IllegalStateException(msg) val port: Int = config["port"] ?: fail("missing port") // type-checks: Nothing <: Int ``` ## JVM / interop mapping The JVM has **no bottom type**. So: - In **return position**, `fun fail(): Nothing` compiles to a `void`-returning JVM method. From Java it is just `void fail(String)`. - As a **type argument** (e.g. `List<Nothing>`) it erases to `Object` after generics erasure; the empty-list pattern `emptyList<Nothing>()` is purely a Kotlin-side convenience. - A bare `null` whose Kotlin type is `Nothing?` carries no special JVM marker — it's just `null`. ## The lost semantics Java callers get **none** of the bottom-type benefits: they see a normal `void` method, so the compiler will **not** treat code after the call as unreachable, will **not** use it for exhaustiveness, and there is no annotation that recreates `Nothing`'s guarantee. The 'never returns' contract is a **Kotlin-compile-time-only** property erased at the JVM boundary. ## Summary - `Nothing` = empty bottom type, subtype of everything, means 'never returns normally'. - Maps to `void` in return position, erases via generics elsewhere. - Drives Kotlin flow/exhaustiveness analysis; **Java sees none of it**.
- Why does `val x = if (c) 1 else throw E()` compile to an Int?`throw` has type `Nothing`, the bottom type. The `if` result type is the least upper bound of `Int` and `Nothing`, which is `Int`, so `x: Int`.
- What is the Kotlin type of the literal `null` with no expected type?`Nothing?` — the nullable bottom type, which is assignable to any nullable type.
Nothing is like a one-way trapdoor: code can fall into it but execution never climbs back out, so whatever type the surrounding slot expects, the trapdoor 'fits'.
saying these in an interview costs you the question
- Calling Nothing 'like void' without noting it is the bottom type / subtype of everything
- Saying Java can detect the 'never returns' contract
- Confusing Nothing with Unit (Unit has one value; Nothing has none)
- Claiming there is a JVM bottom type or a @Nothing annotation