ZetCode

Kotlin get 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的属性系统提供了强大的方式来控制对类成员的访问。 get 关键字对于定义属性的 getter 至关重要。本教程通过实际例子深入探讨了 get 关键字。

基本定义

Kotlin 中的 get 关键字定义了属性的 getter。Kotlin 中的每个属性都有一个默认的 getter,但您可以定义自定义 getter 来控制属性访问。当您读取属性的值时,会调用 getter。

默认 Getter

Kotlin 自动为属性提供一个默认的 getter。默认 getter 只是返回属性值。您无需显式声明它。

DefaultGetter.kt
package com.zetcode

class Person {
    var name: String = "John Doe"
}

fun main() {
    val person = Person()
    println(person.name) // Output: John Doe
}

在这里,name 属性有一个隐式的 getter,它返回其值。当我们访问 person.name 时,会自动调用默认的 getter。

自定义 Getter

您可以使用 get 关键字定义自定义 getter。这允许您在访问属性时修改返回值或添加逻辑。

CustomGetter.kt
package com.zetcode

class Circle(val radius: Double) {
    val area: Double
        get() = Math.PI * radius * radius
}

fun main() {
    val circle = Circle(5.0)
    println(circle.area) // Output: 78.53981633974483
}

在这里,area 是一个计算属性,具有自定义 getter。getter 在每次访问属性时都会计算面积,使用当前的半径值。

带有后备字段的 Getter

属性可以同时具有后备字段和自定义 getter。后备字段存储实际值,而 getter 控制对它的访问。

BackingFieldGetter.kt
package com.zetcode

class Temperature {
    var celsius: Double = 0.0
        get() {
            println("Getting temperature")
            return field
        }
        set(value) {
            field = value
        }
}

fun main() {
    val temp = Temperature()
    temp.celsius = 25.0
    println(temp.celsius) // Output: Getting temperature\n25.0
}

此示例显示了一个同时具有 getter 和 setter 的属性。getter 在返回该值之前打印一条消息。 field 关键字引用存储实际值的后备字段。

带有验证的 Getter

getter 可以包括验证逻辑,以确保返回值满足某些条件。这对于维护数据完整性很有用。

ValidationGetter.kt
package com.zetcode

class User(val birthYear: Int) {
    val age: Int
        get() {
            val currentYear = java.time.Year.now().value
            return currentYear - birthYear
        }
}

fun main() {
    val user = User(1990)
    println(user.age) // Output will vary based on current year
}

age 属性的 getter 根据当年动态计算年龄。这确保了在访问时年龄始终是最新的。

带有可见性修饰符的 Getter

您可以独立于属性修改 getter 的可见性。这允许进行细粒度的访问控制。

VisibilityGetter.kt
package com.zetcode

class BankAccount {
    var balance: Double = 0.0
        private set
    
    val formattedBalance: String
        get() = "$${"%.2f".format(balance)}"
}

fun main() {
    val account = BankAccount()
    // account.balance = 100.0 // Error: setter is private
    println(account.formattedBalance) // Output: $0.00
}

在这里,balance setter 是私有的,而 getter 仍然是公共的。 formattedBalance 属性提供余额的格式化字符串表示形式。

接口中的 Getter

接口可以定义具有 getter 的属性。实现类必须通过存储或计算来提供属性。

InterfaceGetter.kt
package com.zetcode

interface Shape {
    val area: Double
        get() = 0.0
}

class Rectangle(val width: Double, val height: Double) : Shape {
    override val area: Double
        get() = width * height
}

fun main() {
    val rect = Rectangle(4.0, 5.0)
    println(rect.area) // Output: 20.0
}

Shape 接口定义了 area 的默认 getter。 Rectangle 使用其自己的实现覆盖了它。 getter 根据宽度和高度计算面积。

使用 Getter 进行延迟初始化

getter 可以与 by lazy 一起使用来实现延迟初始化。这会延迟计算,直到首次访问该属性。

LazyGetter.kt
package com.zetcode

class DatabaseConfig {
    val connectionString: String by lazy {
        println("Initializing connection")
        "jdbc:mysql://:3306/mydb"
    }
}

fun main() {
    val config = DatabaseConfig()
    println("Config created")
    println(config.connectionString) // Output: Initializing connection\njdbc:...
    println(config.connectionString) // Output: jdbc:... (no reinitialization)
}

只有在首次访问时才会初始化 connectionString。后续访问将返回缓存的值。这对于昂贵的初始化很有用。

Getter 的最佳实践

来源

Kotlin 属性文档

本教程深入介绍了 Kotlin 的 get 关键字,展示了默认 getter 和自定义 getter。我们探讨了各种场景,包括计算属性、延迟初始化和接口实现。正确使用 getter 可以使您的代码更易于维护和高效。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我写了 1400 多篇文章和 8 本电子书。我拥有超过八年的编程教学经验。

列出 所有 Kotlin 教程