相关疑难解决方法(0)

Kotlin - 使用"by lazy"与"lateinit"进行属性初始化

在Kotlin中如果你不想在构造函数或类体的顶部初始化类属性,你基本上有这两个选项(来自语言参考):

  1. 延迟初始化

lazy()是一个函数,它接受一个lambda并返回一个Lazy实例,它可以作为实现一个惰性属性的委托:第一次调用get()执行传递给lazy()的lambda并记住结果,后续调用get()只返回记住的结果.

public class Hello {

   val myLazyString: String by lazy { "Hello" }

}
Run Code Online (Sandbox Code Playgroud)

所以第一次调用和子命令调用,无论它在哪里,到myLazyString将返回"Hello"

  1. 延迟初始化

通常,必须在构造函数中初始化声明为具有非null类型的属性.但是,这通常不方便.例如,可以通过依赖注入或单元测试的设置方法初始化属性.在这种情况下,您无法在构造函数中提供非null初始值设定项,但在引用类体内的属性时仍希望避免空值检查.

要处理这种情况,可以使用lateinit修饰符标记属性:

public class MyTest {

   lateinit var subject: TestSubject

   @SetUp fun setup() { subject = TestSubject() }

   @Test fun test() { subject.method() }
}
Run Code Online (Sandbox Code Playgroud)

修饰符只能用于在类体(不在主构造函数中)内声明的var属性,并且只能在属性没有自定义getter或setter时使用.属性的类型必须为非null,并且它不能是基本类型.

那么,如何在这两个选项之间正确选择,因为它们都可以解决同样的问题?

properties kotlin

232
推荐指数
7
解决办法
7万
查看次数

Kotlin:检查lazy val是否已初始化

有没有办法判断是否在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"变量是否已初始化?

kotlin

32
推荐指数
3
解决办法
7077
查看次数

标签 统计

kotlin ×2

properties ×1