What is an `init {}` block in Kotlin, and when does its code run relative to the primary constructor?
answer
- Primary constructor has no body — init is its body
- Runs at construction, every instance
- Can read constructor params directly
- require/check for validation
- Multiple inits run in declaration order
basics
~20 sAn init {} block holds setup code that runs when you create an object. It runs as part of the primary constructor, after the constructor parameters are available but as the object is being built.
solid answer
~30 sAn `init {}` block is an initializer block tied to the primary constructor. Kotlin's primary constructor has no body, so `init` is where you put construction logic. Its code runs during object construction and can read the primary-constructor parameters directly (e.g. `init { require(age >= 0) }`). A class may have several `init` blocks; they execute top-to-bottom in declaration order, interleaved with property initializers. `init` runs every time an instance is created, before the constructor returns, so it's the place for validation (`require`/`check`) or derived setup. It cannot take parameters and has no name.
code
kotlin · 7 linesclass Account(initialBalance: Long) {
val balance: Long
init {
require(initialBalance >= 0) { "balance cannot be negative" }
balance = initialBalance
}
}go deeper
Knows init is construction code that can validate inputs and read constructor params.
Explains init runs as part of the primary constructor and uses require/check correctly.
Frames init relative to property initializers and the no-body primary constructor; discusses invariant enforcement.
Considers when to push logic out of init (e.g. factory functions) and the testability/exception-safety tradeoffs of heavy construction logic.
## What an `init` block is Kotlin's **primary constructor** is the declaration in the class header: `class User(val name: String)`. It has **no body** of its own — there is nowhere to write statements. The `init {}` block fills that gap: it is a block of code that runs as part of the primary constructor. ```kotlin class User(name: String) { val displayName: String init { require(name.isNotBlank()) { "name must not be blank" } displayName = name.trim() } } ``` ## Key facts - **Runs during construction:** `init` executes every time an instance is created, as part of the primary constructor, before the constructor returns and before any secondary-constructor body. - **Sees constructor parameters:** code in `init` can reference the primary-constructor parameters directly (`name` above), even ones not marked `val`/`var`. - **No name, no parameters, no return:** you cannot call an `init` block directly or pass it arguments. - **Multiple allowed:** a class can declare several `init` blocks; they run **in the order they appear**. - **Common uses:** validation with `require(...)` (throws `IllegalArgumentException`) or `check(...)` (throws `IllegalStateException`), and computing derived properties. ## Property initializers vs init A property initializer like `val x = 5` is itself initialization code. Property initializers and `init` blocks form a single sequence that runs top-to-bottom in declaration order. So `init` is not "after all properties" — it's wherever it sits in the file relative to them. ## Why it matters Use `init` to keep an object's invariants true from the moment it exists: reject bad input early and compute consistent derived state.
- Can an `init` block take parameters?No. It has no name and no parameter list; it implicitly uses the primary-constructor parameters in scope.
- What exception does `require` throw vs `check`?`require` throws `IllegalArgumentException` (bad arguments); `check` throws `IllegalStateException` (bad state).
The primary constructor is a form you fill in (the parameters); the init block is the clerk who validates and files it before handing you the finished record.
saying these in an interview costs you the question
- Saying init runs once per class instead of once per instance
- Claiming init runs after the constructor returns
- Thinking init can be called manually like a method
- Believing init cannot access constructor parameters
- Confusing init with a companion-object or static initializer