Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Kotlin Dictionary

  1. Home
  2. Kotlin Dictionary
  3. Delegated Properties

Delegated Properties

Since: Kotlin 1.0(2016)

Delegation is a mechanism that hands off property read/write operations to another object. Use the by keyword to specify a standard delegated property or a custom delegate.

Syntax

var propertyName: Type by delegateObject

// Delegated properties from the standard library
import kotlin.properties.Delegates

var propertyName: Type by Delegates.observable(initialValue) { prop, old, new -> }
var propertyName: Type by Delegates.notNull()

Delegate Types

DelegateDescription
by lazy { }A lazy property that is initialized on first access.
Delegates.observable(initialValue) { prop, old, new -> }Invokes a callback whenever the value changes. Use this to observe property changes.
Delegates.vetoable(initialValue) { prop, old, new -> }Updates the value only when the callback returns true. Use this for validation.
Delegates.notNull()Allows declaration without an initial value, but throws an exception if accessed before initialization.

Sample Code

sample_delegated_property.kt
import kotlin.properties.Delegates

class User {
    // Logs a message whenever the value changes.
    var name: String by Delegates.observable("(not set)") { _, old, new ->
        println("Name changed: $old → $new")
    }

    // Updates the value only if the new value is 0 or greater.
    var age: Int by Delegates.vetoable(0) { _, _, new ->
        new >= 0
    }

    // Requires initialization before access.
    var id: Int by Delegates.notNull()
}

fun main() {
    val user = User()
    user.id = 1001 // Initializes the notNull property.
    user.name = "Okabe Rintaro" // Callback is invoked.
    user.name = "Makise Kurisu" // Callback is invoked again.

    user.age = 18
    println(user.age) // 18
    user.age = -1 // Rejected because the value is negative.
    println(user.age) // 18 (unchanged)
}

The command looks like this:

kotlinc sample_delegated_property.kt -include-runtime -d sample_delegated_property.jar
java -jar sample_delegated_property.jar
Name changed: (not set) → Okabe Rintaro
Name changed: Okabe Rintaro → Makise Kurisu
18
18

Common Mistakes

A notNull() property throws an exception if accessed before being initialized. by lazy is only for val — it cannot be used with var.

import kotlin.properties.Delegates

class LabMember {
    // NG: notNull must be initialized before access
    var name: String by Delegates.notNull()
    // println(name) ← throws IllegalStateException before initialization

    // NG: by lazy cannot be used with var (compile error)
    // var lazyProp: String by lazy { "init" }

    // NG: vetoable lambda must return Boolean; returning Unit causes a compile error
    // var divergence: Double by Delegates.vetoable(0.0) { _, _, new ->
    //     println(new) // Unit returned — compile error
    // }
}
sample_delegated_property_mistakes.kt
import kotlin.properties.Delegates

class LabMember {
    var name: String by Delegates.notNull() // Initialize before accessing

    val lazyProp: String by lazy { // Declare with val
        println("Initializing")
        "lab member"
    }

    var divergence: Double by Delegates.vetoable(0.0) { _, _, new ->
        new in 0.0..2.0 // Return a Boolean expression
    }
}

fun main() {
    val okabe = LabMember()
    okabe.name = "Okabe Rintaro"
    println(okabe.name) // Okabe Rintaro

    println(okabe.lazyProp) // Initializing → lab member
    println(okabe.lazyProp) // lab member (not initialized again)

    okabe.divergence = 1.048596
    println(okabe.divergence) // 1.048596
    okabe.divergence = 3.0 // Out of range, rejected
    println(okabe.divergence) // 1.048596 (unchanged)
}

The command looks like this:

kotlinc sample_delegated_property_mistakes.kt -include-runtime -d sample_delegated_property_mistakes.jar
java -jar sample_delegated_property_mistakes.jar
Okabe Rintaro
Initializing
lab member
lab member
1.048596
1.048596

Details

Delegated properties let you extract property access logic into reusable classes. Simply place a delegate object after the by keyword to handle complex access behavior in a clean, concise way.

Delegates.observable is useful when you want to observe value changes, and Delegates.vetoable is convenient when you need to validate changes before they are applied. To create a custom delegate, implement the ReadWriteProperty<T, V> interface and define both getValue and setValue.

If you find any errors or copyright issues, please .