Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Kotlin辞典

  1. トップページ
  2. Kotlin辞典
  3. 委譲プロパティ

委譲プロパティ

プロパティの読み書き処理を別のオブジェクトに委譲する仕組みです。『by』キーワードで標準の委譲プロパティや自作デリゲートを指定できます。

構文
// 委譲プロパティの基本構文
var プロパティ名: 型 by デリゲートオブジェクト

// 標準ライブラリの委譲プロパティ
import kotlin.properties.Delegates

var プロパティ名: 型 by Delegates.observable(初期値) { prop, old, new -> }
var プロパティ名: 型 by Delegates.notNull()
構文一覧
デリゲート概要
by lazy { }初回アクセス時に初期化する遅延プロパティです。
Delegates.observable(初期値) { prop, old, new -> }値が変わるたびにコールバックを呼び出します。変更を監視したいプロパティに使います。
Delegates.vetoable(初期値) { prop, old, new -> }コールバックが『true』を返した場合のみ値を更新します。バリデーションに使います。
Delegates.notNull()初期値なしで宣言できますが、初期化前にアクセスすると例外が発生します。
サンプルコード
import kotlin.properties.Delegates

class User {
    // 値の変更をログに出力します。
    var name: String by Delegates.observable("(未設定)") { _, old, new ->
        println("名前が変更されました: $old → $new")
    }

    // 0以上の場合のみ値を更新します。
    var age: Int by Delegates.vetoable(0) { _, _, new ->
        new >= 0
    }

    // 初期化を必須にします。
    var id: Int by Delegates.notNull()
}

fun main() {
    val user = User()
    user.id = 1001          // notNull の初期化
    user.name = "田中"       // コールバックが呼ばれます。
    user.name = "鈴木"       // 再度コールバックが呼ばれます。

    user.age = 25
    println(user.age)        // 25
    user.age = -1            // 0未満は拒否されます。
    println(user.age)        // 25(変わっていない)
}
概要

委譲プロパティは、プロパティのアクセスロジックを再利用可能なクラスに切り出す仕組みです。『by』の後ろにデリゲートオブジェクトを指定するだけで、複雑なアクセス処理をシンプルに記述できます。

『Delegates.observable』は値の変更を監視したいとき、『Delegates.vetoable』はバリデーションを挟みたいときに便利です。自作のデリゲートを作る場合は『ReadWriteProperty<T, V>』インターフェースを実装して『getValue』と『setValue』を定義してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。