Kotlin 屬性 (Properties)

在 Java 中,我們習慣定義 private 欄位,然後手寫 public getXxx()setXxx()。 在 Kotlin 中,這一切都被簡化為 Properties (屬性)

自動產生 Accessor

當你宣告一個屬性時,編譯器會自動幫你產生 Getter (若是 var 則會產生 Setter)。

class Person {
    var name: String = "Miko"
        // 預設會有 get() = field 和 set(value) { field = value }
}

fun main() {
    val p = Person()
    p.name = "Jason" // 實際上是呼叫 p.setName("Jason")
    println(p.name)  // 實際上是呼叫 p.getName()
}

自訂 Getter / Setter

如果你想在存取屬性時加入邏輯:

class Rectangle(val width: Int, val height: Int) {
    // 每次存取 area 時都會重新計算
    val area: Int
        get() = width * height
}

Backing Field (field)

如果你在 Setter 中直接寫 this.name = value,會造成無窮遞迴呼叫 Setter。 Kotlin 提供了一個特殊的標識符 field,代表屬性實際存值的地方。

var counter = 0
    set(value) {
        if (value >= 0) {
            field = value // 正確寫法
        }
    }
    }

封裝 (Backing Properties)

如果你希望「對外唯讀,對內可寫」,可以用這個模式:

class Data {
    private var _table: Map<String, Int>? = null
    val table: Map<String, Int>
        get() {
            if (_table == null) {
                _table = HashMap() // load data
            }
            return _table ?: throw AssertionError("Set to null by another thread")
        }
}

檢查 lateinit

可以用 ::prop.isInitialized 來檢查 lateinit 變數是否已初始化。

if (::message.isInitialized) {
    println(message)
}