Constructors and Init Blocks in Kotlin

In Kotlin, constructors and init blocks provide a structured way to initialize objects and perform setup tasks. Kotlin simplifies object creation by supporting primary and secondary constructors along with initialization blocks.

1. Why Constructors and Init Blocks Matter

Constructors and init blocks help in setting up the initial state of objects:

2. Primary Constructor

The primary constructor is a concise way to initialize a class. It is defined in the class header:


class Person(val name: String, var age: Int) 

  

2.1 Using Init Blocks

The init block is executed when the object is created and can contain initialization logic:


class Person(val name: String, var age: Int) {
    init {
        println("Person object created: $name, Age: $age") 
        
        
    }
}
  

Example:


fun main() {
    val person = Person("Alice", 25)
    
}
  

Output:


Person object created: Alice, Age: 25
  

3. Secondary Constructor

Secondary constructors allow multiple ways to initialize a class. They are defined inside the class body using the constructor keyword:


class Person {
    var name: String
    var age: Int

    constructor(name: String) {
        this.name = name
        this.age = 0
        
    }

    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
        
    }
}
  

Example:


fun main() {
    val person1 = Person("Bob") // Uses first secondary constructor
    val person2 = Person("Charlie", 30) // Uses second secondary constructor
    println("${person1.name}, ${person1.age}") // Bob, 0
    println("${person2.name}, ${person2.age}") // Charlie, 30
}
  

4. Combining Init Blocks and Constructors

You can combine primary constructors, secondary constructors, and init blocks to handle complex initialization:


class Person(val name: String, var age: Int) {

    init {
        println("Init block: $name, Age: $age")
        if(age < 0) age = 0
        
    }

    constructor(name: String) : this(name, 0) {
        println("Secondary constructor called for $name")
        
    }
}
  

Example:


fun main() {
    val person1 = Person("David", 28) // Primary constructor called
    val person2 = Person("Eve")       // Secondary constructor called
}
  

Output:


Init block: David, Age: 28
Init block: Eve, Age: 0
Secondary constructor called for Eve
  

5. Execution Order of Constructors and Init Blocks

Here’s the order when an object is created:

  1. If you call a secondary constructor that delegates to a primary constructor, the primary constructor runs first.
  2. Then, all init blocks execute in the order they appear in the class.
  3. Finally, the code inside the secondary constructor runs.

If you don’t delegate to the primary constructor, the secondary constructor runs directly and init blocks are not executed.

6. Technical Interview Questions

7. Key Takeaways