ProgrammingAndroid Developer

What are constructors in Kotlin, what types are there, and how does object initialization work using primary and secondary constructors?

Pass interviews with Hintsage AI assistant

Answer.

History of the issue:

In Kotlin, constructors have simplified the declaration and initialization of objects compared to Java. The language features two types of constructors: primary constructor and secondary constructors. This allows developers to manage the initialization process and have more flexibility in creating class instances.

Problem:

In Kotlin programming, it is important to understand the benefits of clearly distinguishing between the types of constructors and how this affects code readability, safety, and extensibility. A common mistake is the incorrect combination or overriding of initialization, which can lead to unexpected bugs.

Solution:

In Kotlin, the primary constructor is declared immediately after the class name and can be extended with the keyword constructor. Secondary constructors are declared within the class body and must always delegate the call to another constructor via this() or to the base constructor via super().

Code example:

class User(val name: String) { // primary constructor var age: Int = 0 constructor(name: String, age: Int) : this(name) { // secondary constructor this.age = age } }

Key features:

  • The primary constructor is simple and used for main properties
  • Secondary constructors are needed for additional scenarios and overloading
  • Initializers (init blocks) in Kotlin are executed for every object creation and can access the parameters of the primary constructor

Trick questions.

What is the difference between an init block and a constructor body?

The init block is used for general initialization for every object creation via any constructor, while the body of the secondary constructor runs only when the specific secondary constructor is called.

class Example(val x: Int) { init { println("Initialized with x = $x") } constructor(x: Int, y: Int) : this(x) { println("Secondary constructor called with y = $y") } }

Is it possible to forgo the secondary constructor and always use only the primary?

Yes, if all the logic of your class fits into property initialization and init blocks. A secondary constructor is required only for special cases of overloading or specific logic.

What will happen if a secondary constructor does not delegate to the primary constructor?

In Kotlin, this is prohibited — the compiler will raise an error: every secondary constructor must either explicitly call another secondary or the primary one via this().

Common mistakes and anti-patterns

  • Attempting to duplicate initialization in multiple constructors
  • Using a secondary constructor unnecessarily
  • Lack of delegation in a secondary constructor

Real-life example

Negative case

The project added many secondary constructors for each initializer variant of the class, making the code bulky.

Pros:

  • Flexible initialization

Cons:

  • Code duplication, high maintainability, errors when changing class structure

Positive case

Used a primary constructor, init block, and factory methods in a companion object for different object creation scenarios.

Pros:

  • Simplicity, minimal duplicable code, easy maintenance, transparent initialization

Cons:

  • Requires thoughtfulness in the API of factory methods