Kotlin get 关键字
最后修改于 2025 年 4 月 19 日
Kotlin 的属性系统提供了强大的方式来控制对类成员的访问。 get 关键字对于定义属性的 getter 至关重要。本教程通过实际例子深入探讨了 get 关键字。
基本定义
Kotlin 中的 get 关键字定义了属性的 getter。Kotlin 中的每个属性都有一个默认的 getter,但您可以定义自定义 getter 来控制属性访问。当您读取属性的值时,会调用 getter。
默认 Getter
Kotlin 自动为属性提供一个默认的 getter。默认 getter 只是返回属性值。您无需显式声明它。
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。这允许您在访问属性时修改返回值或添加逻辑。
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 控制对它的访问。
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 可以包括验证逻辑,以确保返回值满足某些条件。这对于维护数据完整性很有用。
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 的可见性。这允许进行细粒度的访问控制。
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 的属性。实现类必须通过存储或计算来提供属性。
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 一起使用来实现延迟初始化。这会延迟计算,直到首次访问该属性。
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 的最佳实践
- 保持 getter 简单: getter 通常应该快速且没有副作用。
- 考虑缓存: 对于昂贵的计算,请考虑将结果缓存在后备字段中。
- 保持一致性: 确保 getter 始终根据对象的状态返回一致的值。
- 使用延迟初始化: 对于初始化成本高昂的属性,请考虑使用
by lazy。 - 记录行为: 清楚地记录自定义 getter 中的任何非平凡行为。
来源
本教程深入介绍了 Kotlin 的 get 关键字,展示了默认 getter 和自定义 getter。我们探讨了各种场景,包括计算属性、延迟初始化和接口实现。正确使用 getter 可以使您的代码更易于维护和高效。
作者
列出 所有 Kotlin 教程。