Kotlin 如何测试lateinit变量是否从类外部初始化科特林

Kotlin 如何测试lateinit变量是否从类外部初始化科特林,kotlin,Kotlin,概述如何测试lateinit变量是否已初始化。然而,在这个示例中,lateinit变量方便地位于同一个类中 你如何在课外做同样的事情?我的情况就是这样: Foo.kt class Foo { lateinit var foo: String } class Bar { fun doSomething() { val foo = Foo().foo if (::foo.isInitialized) { // Unsupported [referen

概述如何测试lateinit变量是否已初始化。然而,在这个示例中,lateinit变量方便地位于同一个类中

你如何在课外做同样的事情?我的情况就是这样:

Foo.kt

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

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

解决方法是什么?

如果另一个类的对象必须根据是否初始化属性做出决定,那么,对该属性进行初始化——或者回答它是否已经被初始化——是您对象的公共业务能力,因此我建议您通过
public fun isfooInitialized()将其作为公共API的一部分:Boolean
函数,利用对象本身可以检查其
lateinit
属性的状态这一事实

如果这能起作用,你需要做

val foo = Foo()
if (foo::foo.isInitialized)
    //... 
这样做的方式是,尝试获取局部变量的属性引用,而该变量不是属性。这就是为什么错误会说“还不支持对变量的引用”,而不是“此时无法访问备份字段”。另外,在分配局部变量时,您将访问
lateinit
属性的getter,因此如果它还没有初始化,它将失败

但由于编译器的限制,它无法工作。您可以简单地添加一个getter

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

但是如果外部类需要检查某个特定的公共属性是否已经初始化,我会说这个设计的封装性非常差。在我看来,
的任何使用都是初始的
一开始就是一种代码味道。如果您需要使用
isInitialized
来保护对getter的调用,那么最好将属性改为null。然后,您可以使用熟悉的null检查习惯用法,而不是诉诸反射,并且它将以熟悉的方式工作,甚至对于访问它的外部类也是如此。

这里的想法是,我想使用lateinit,因为变量永远不会为null(除非它尚未初始化)我知道我可以简单地使变量为null,但这意味着“null”将是变量的合法状态,而不是。