The init Block
In this page:
class ClassName(val property: Type) {
init {
require(condition) { "message" } // runs when created
}
}
Running Setup Code with init
An init block contains code that runs immediately when an instance is created, useful for validation or setup logic that goes beyond a simple property assignment.
Example: Running Setup Code with init
// Define a class `Person`
class Person(val name: String, val age: Int) {
init {
// Print "Creating person: $name, age $age" to the console, with a trailing newline
println("Creating person: $name, age $age")
}
}
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `person`, set to `Person("Ana", 30)`
val person = Person("Ana", 30)
// Print "Created: ${person.name}" to the console, with a trailing newline
println("Created: ${person.name}")
}
Login to try C/C++/Java/PHP code in the editor
Validating Constructor Arguments
A common use of init is to validate the values passed to the primary constructor, throwing an exception immediately if something is invalid.
Example: Validating Constructor Arguments
// Define a class `Age`
class Age(val value: Int) {
init {
require(value >= 0) { "Age cannot be negative" }
}
}
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `age`, set to `Age(25)`
val age = Age(25)
// Print "Valid age: ${age.value}" to the console, with a trailing newline
println("Valid age: ${age.value}")
}
Login to try C/C++/Java/PHP code in the editor
Multiple init Blocks and Property Order
A class can contain more than one init block, and Kotlin runs them, interleaved with property initializers, in the exact top-to-bottom order they appear in the class body.
Example: Multiple init Blocks and Property Order
// Define a class `Steps`
class Steps {
// Declare a read-only variable `first`, set to `println("Step 1: property initialized").let { "done" }`
val first = println("Step 1: property initialized").let { "done" }
init {
// Print "Step 2: first init block" to the console, with a trailing newline
println("Step 2: first init block")
}
// Declare a read-only variable `second`, set to `println("Step 3: second property initialized").let { "done" }`
val second = println("Step 3: second property initialized").let { "done" }
init {
// Print "Step 4: second init block" to the console, with a trailing newline
println("Step 4: second init block")
}
}
// Entry point: execution of the program starts here
fun main() {
Steps()
}
Login to try C/C++/Java/PHP code in the editor
init Blocks with Secondary Constructors
Because every secondary constructor must delegate to the primary constructor, init blocks always run before a secondary constructor's own body executes.
Example: init Blocks with Secondary Constructors
// Define a class `Logger`
class Logger(val prefix: String) {
init {
// Print "[$prefix] Logger initialized" to the console, with a trailing newline
println("[$prefix] Logger initialized")
}
constructor() : this("DEFAULT") {
// Print "Secondary constructor body running" to the console, with a trailing newline
println("Secondary constructor body running")
}
}
// Entry point: execution of the program starts here
fun main() {
Logger()
}
Login to try C/C++/Java/PHP code in the editor
- Forgetting that multiple
initblocks and property initializers run in the exact order they are written in the class body, not in a separate fixed order. - Putting logic in
initthat depends on a secondary constructor's parameter, forgettinginitblocks run before secondary constructor bodies (but after the primary constructor's own delegation). - Duplicating validation logic in every secondary constructor instead of placing shared checks in an
initblock once.
initblocks run as part of instance creation, in the order they appear alongside property initializers in the class body.- A class can have multiple
initblocks, and they execute top-to-bottom interleaved with property initialization. initblocks can access primary constructor parameters directly, since they run as part of primary construction.- Validation logic common to every instance is often placed in an
initblock rather than repeated per constructor.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: