skip to content

Unit, Nothing & void Mapping

A Unit-returning function compiles to void, though in functional positions the Unit instance is real, and Nothing has no Java equivalent at all. It is a good question for checking that you distinguish the language's type system from the JVM's.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

How does a Kotlin function that returns Unit appear when called from Java, and what is the JVM bytecode return type?

level: juniorimportance: must knowfreq 70%

answer

  1. Unit return type ⇒ bytecode void (V)
  2. Unit is a real type, single value Unit.INSTANCE
  3. void cannot be a generic arg ⇒ Function0<Unit> needs Unit.INSTANCE
  4. Java sees void greet(), not Unit greet()

basics

~10 s

A Kotlin function returning Unit looks like a normal void method in Java. The JVM return type is void, so Java callers just call it and get nothing back.

solid answer

~30 s

Kotlin's Unit is a real type with a single value (the Unit.INSTANCE singleton), but when it is the declared return type of a function, the Kotlin compiler emits a JVM method with return type void. So from Java a `fun greet(): Unit` is just `void greet()` — there is no Unit value to handle, and Java code calls it like any void method. The Unit object only materializes when Unit is used in a generic/functional position (e.g. a `Function0<Unit>`), where void cannot appear and Kotlin must return Unit.INSTANCE. For a plain top-level or member function the bytecode descriptor ends in `)V`.

code

kotlin · 5 lines
kotlin
fun log(msg: String): Unit { println(msg) }        // bytecode: void log(String)
val action: () -> Unit = { println("run") }         // Function0<Unit>, invoke returns Unit.INSTANCE
// From Java:
//   obj.log("hello");                                // void call
//   Function0<Unit> a = () -> { ...; return Unit.INSTANCE; };

go deeper

for a junior

Knows Unit ≈ void and that Java sees a void method; can call it normally.

for a middle

Explains the bytecode descriptor V and that Unit is a real singleton type.

for a senior

Distinguishes return-position (void) from generic/functional position (Unit.INSTANCE) and explains why.

for a principal

Connects this to JVM generic erasure constraints and the design rationale for a uniform single-value Unit type vs Java's special-cased void.

## What `Unit` is `Unit` is Kotlin's type for "this function returns no meaningful value" — the rough equivalent of `void` in Java. Unlike Java's `void`, `Unit` is a **real type** with exactly **one value**, accessed as `Unit` (the `Unit.INSTANCE` singleton in Java). Every Kotlin function has a return type; functions that would be `void` in Java have return type `Unit`, which can be omitted in source. ## How it compiles When `Unit` is the **declared return type of a function**, the compiler emits a JVM method whose return descriptor is `V` (void). So: ```kotlin fun greet(name: String): Unit { println("hi $name") } // or, equivalently, with the type omitted: fun greet2(name: String) { println("hi $name") } ``` both compile to `public void greet(String)`. From Java you call `obj.greet("x");` — there is **no return value** to capture. ## When the `Unit` object appears The `Unit.INSTANCE` singleton only materializes in **functional / generic positions**, where the JVM has no `void` type for a type argument. A `() -> Unit` lambda becomes a `Function0<Unit>`, and its `invoke()` must `return Unit.INSTANCE;`. Java code wiring such a lambda must explicitly return that: ```java Function0<Unit> f = () -> { System.out.println("x"); return Unit.INSTANCE; }; ``` ## Summary - Plain `Unit`-returning function ⇒ bytecode `void`, called normally from Java. - `Unit` as a **type argument** ⇒ the real `Unit.INSTANCE` object is required. - `Unit` is referenced from Java as `kotlin.Unit`.

  • Why can't the compiler just use void for a () -> Unit lambda?
    JVM generics are reference-type only; `void` is not a type and cannot be a type argument. The function interface is `Function0<R>`, so R must be a real type — Kotlin uses `Unit` and returns `Unit.INSTANCE`.
  • How do you reference Unit from Java code?
    As `kotlin.Unit`, and its singleton as `kotlin.Unit.INSTANCE`.

Unit is like a sealed empty box: at the door (function return) it's flattened to 'nothing' (void), but inside a container slot (generic) you still need the box object.

saying these in an interview costs you the question

  • Claiming Unit-returning functions compile to a method returning a Unit object instead of void
  • Saying Unit and Java void are identical (Unit is a real type with a value)
  • Thinking you must return something from a void Kotlin function in Java
  • Believing a () -> Unit lambda compiles to a void-returning JVM method

context

open as a page

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'?

level: middleimportance: must knowfreq 55%

basics

~20 s

Nothing 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.

open as a page

When you pass a Kotlin lambda or SAM-like callback to Kotlin from Java, when must Java code return Unit.INSTANCE, and why?

level: middleimportance: should knowfreq 45%

basics

~10 s

If the Kotlin API takes a function type like () -> Unit, Java must implement Kotlin's Function interface and explicitly return Unit.INSTANCE; because the function's generic return type is Unit, not void.

open as a page

Distinguish Unit, Unit?, Nothing, and Nothing? — what does each mean and how does each behave at the JVM/interop boundary?

level: seniorimportance: should knowfreq 35%

basics

~10 s

Unit has one value; Unit? adds null. Nothing has no values and means 'never returns'; Nothing? has exactly one value, null. Each maps differently when crossing into Java.

open as a page

You expose a Kotlin API using Unit and Nothing in generic positions to Java consumers. What erasure and interop pitfalls arise, and how do you design around them?

level: seniorimportance: nice to knowfreq 22%

basics

~20 s

In generics, Unit and Nothing erase to Object, and Java loses their special meaning. Java sees raw Function interfaces or Object slots, must return Unit.INSTANCE, and gets no 'never returns' guarantee — so design SAM/void APIs for Java.

open as a page