Skip to content
AgileLogics
6 min read

Constructors, init, and Properties

Prerequisites: Classes and objects

Kotlin properties can validate their values, compute them on demand, and control who may change them.

init blocks — validate on creation

Code in an init block runs when an object is created:

class Temperature(val celsius: Double) {
    init {
        require(celsius >= -273.15) { "Below absolute zero: $celsius" }
    }

    val fahrenheit: Double
        get() = celsius * 9 / 5 + 32
}

fun main() {
    val t = Temperature(25.0)
    println(t.fahrenheit)

    try {
        Temperature(-300.0)
    } catch (e: IllegalArgumentException) {
        println(e.message)
    }
}
77.0
Below absolute zero: -300.0
  • require(condition) { message } throws IllegalArgumentException if the condition is false — the standard way to reject bad arguments.
  • fahrenheit has a custom getter: it's calculated each time it's read, so it's always in sync with celsius.

Default values and named arguments

Constructor parameters support defaults and named arguments, just like functions:

class Settings(val fontSize: Int = 14, val theme: String = "light")

fun main() {
    val s = Settings(theme = "dark")
    println("${s.fontSize} ${s.theme}")
}
14 dark

Custom setters and private set

class Counter {
    var count = 0
        private set

    var step = 1
        set(value) {
            require(value > 0) { "step must be positive" }
            field = value
        }

    fun increment() {
        count += step
    }
}

fun main() {
    val c = Counter()
    c.step = 5
    c.increment()
    c.increment()
    println(c.count)
}
10
  • private set — anyone can read count, but only the class can change it.
  • In a custom setter, field refers to the property's stored value.

lateinit

lateinit var declares a non-null property that will be set later — common in frameworks (Android, testing) that create objects first and fill them in afterwards:

class Screen {
    lateinit var title: String
}

Reading it before it's set throws UninitializedPropertyAccessException. Prefer constructor parameters where you can.

Common mistakes

  • Using a custom setter that assigns to the property itself (count = value) instead of field — that calls the setter again forever, and the program crashes with a StackOverflowError.