面试题答案
一键面试Kotlin属性代理模式中委托属性的工作原理
在Kotlin中,委托属性允许将属性的访问器(getter和setter)的实现委托给另一个对象(即代理)。当一个属性使用委托属性语法定义时,Kotlin编译器会在背后生成代码,将属性访问请求转发给代理对象的相应方法。
委托属性基于by
关键字,语法如下:
class MyClass {
var myProperty: String by MyDelegate()
}
class MyDelegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
// 返回属性值的逻辑
return "default value"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
// 设置属性值的逻辑
}
}
在上述代码中:
MyClass
类中的myProperty
属性通过by
关键字委托给MyDelegate
类的实例。MyDelegate
类需要提供getValue
和setValue
操作符函数。getValue
函数用于获取属性值,接收两个参数:thisRef
(委托属性所在类的实例)和property
(表示委托属性本身的KProperty<*>
对象)。setValue
函数用于设置属性值,除了thisRef
和property
外,还接收要设置的新值。
实际开发场景中运用委托属性解决常见问题 - 实现延迟加载属性
延迟加载属性是指属性的值在首次访问时才进行计算,而不是在对象创建时就计算。在Kotlin中可以使用lazy
函数来实现延迟加载属性。lazy
函数返回一个Lazy<T>
类型的对象,该对象作为委托用于延迟加载属性。
示例代码如下:
class DataLoader {
val data: String by lazy {
// 模拟加载数据的耗时操作
Thread.sleep(2000)
"Loaded data"
}
}
fun main() {
val loader = DataLoader()
println("Before accessing data")
println(loader.data) // 首次访问,触发数据加载
println("After first access")
println(loader.data) // 再次访问,直接返回已加载的数据
}
在上述代码中:
DataLoader
类中的data
属性通过lazy
函数进行委托。lazy
函数的lambda表达式中的代码会在data
属性首次被访问时执行。- 第一次访问
loader.data
时,会执行lazy
函数lambda表达式中的模拟耗时操作(Thread.sleep(2000)
),并返回计算结果。之后再次访问data
属性时,直接返回第一次计算的结果,不会再次执行lambda表达式中的代码,从而实现了延迟加载。