如何测试lateinit var是否从类外部初始化? -科特林

时间:2020-03-20 18:47:36

标签: kotlin

This SO post概述了如何测试lateinit var是否已初始化。但是,在该示例中,lateinit var方便地位于同一类中。

您如何在课堂上( 之外)做同样的事情?这是我的情况:

Foo.kt

class Foo {
    lateinit var foo: String
}

Bar.kt

class Bar {
    fun doSomething() {
        val foo = Foo().foo
        if (::foo.isInitialized) { // Unsupported [reference to variables aren't supported yet]
            Log.i("TAG", "do something")
        }
    }
}

此问题的解决方法是什么?

2 个答案:

答案 0 :(得分:2)

如果这行得通,那么您需要做

val foo = Foo()
if (foo::foo.isInitialized)
    //... 

您这样做的方式是尝试获取本地变量(不是属性)的属性引用。这就是为什么错误显示“尚不支持对变量的引用”而不是“此时无法访问后备字段”的原因。另外,在分配局部变量时,您将访问lateinit属性的getter,因此,如果尚未初始化,它将失败。

但是由于编译器的限制,它不起作用。您只需添加吸气剂

val fooReady: Boolean get() = ::foo.isInitialized 

但是我要说的是,如果外部类需要检查特定的公共属性是否已初始化,则设计的封装性很差。我认为,isInitialized的任何使用都是从代码气味开始的。如果您需要使用isInitialized保护对getter的调用,则最好使该属性为可空。然后,您可以使用熟悉的null检查习惯用法,而不必求助于反射,即使对于访问它的外部类,它也将以熟悉的方式工作。

答案 1 :(得分:0)

如果另一类的对象必须根据该属性是否已初始化来做出决定,那么初始化此属性(或回答是否已初始化)是您对象的公共业务能力,因此我建议您通过public fun isFooInitialised(): Boolean函数简单地使其成为公共API的一部分,该函数利用了对象本身可以检查其lateinit属性状态的事实。