有没有办法判断是否在Kotlin中初始化了懒惰的val而没有在此过程中初始化它?
例如,如果我有一个懒惰的val,查询它是否为null将实例化它
val messageBroker: MessageBroker by lazy { MessageBroker() }
if (messageBroker == null) {
// oops
}
Run Code Online (Sandbox Code Playgroud)
我可能会使用第二个变量,但这看起来很混乱.
private var isMessageBrokerInstantiated: Boolean = false
val messageBroker: MessageBroker by lazy {
isMessageBrokerInstantiated = true
MessageBroker()
}
...
if (!isMessageBrokerInstantiated) {
// use case
}
Run Code Online (Sandbox Code Playgroud)
是否有一些性感的方式来确定这一点,比如if (Lazy(messageBroker).isInstantiated())?
相关(但不相同):如何检查"lateinit"变量是否已初始化?
vod*_*dan 38
有一种方法,但您必须访问由lazy {}以下方式返回的委托对象:
val messageBrokerDelegate = lazy { MessageBroker() }
val messageBroker by messageBrokerDelegate
if(messageBrokerDelegate.isInitialized())
...
Run Code Online (Sandbox Code Playgroud)
isInitialized是接口上的公共方法Lazy<T>,这里是文档.
hot*_*key 24
从Kotlin 1.1开始,您可以直接使用属性委托.getDelegate().
您可以为属性引用编写扩展属性,以检查它是否Lazy具有已初始化的委托:
/**
* Returns true if a lazy property reference has been initialized, or if the property is not lazy.
*/
val KProperty0<*>.isLazyInitialized: Boolean
get() {
if (this !is Lazy<*>) return true
// Prevent IllegalAccessException from JVM access check on private properties.
val originalAccessLevel = isAccessible
isAccessible = true
val isLazyInitialized = (getDelegate() as Lazy<*>).isInitialized()
// Reset access level.
isAccessible = originalAccessLevel
return isLazyInitialized
}
Run Code Online (Sandbox Code Playgroud)
然后在使用网站:
val messageBroker: MessageBroker by lazy { MessageBroker() }
if (this::messageBroker.isLazyInitialized) {
// ... do stuff here
}
Run Code Online (Sandbox Code Playgroud)
此解决方案需要kotlin-reflect位于类路径上.使用Gradle,使用compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
该isAccessible = true部分是必需的.getDelegate(),因为否则它无法访问存储委托引用的私有字段.
在热键的解决方案的基础上,您可以创建一个isLazyInitialized属性(而不是函数),以与lateinit变量的isInitialized属性保持一致.
此外,没有必要处理null情况.
import kotlin.reflect.KProperty0,
import kotlin.reflect.jvm.isAccessible
val KProperty0<*>.isLazyInitialized: Boolean
get() {
// Prevent IllegalAccessException from JVM access check
isAccessible = true
return (getDelegate() as Lazy<*>).isInitialized()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7077 次 |
| 最近记录: |