isInitialized - 此时无法访问lateinit var的后备字段

Ele*_*gyD 32 java kotlin kotlin-lateinit

我正在尝试检查lateinit属性是否已初始化.
在Kotlin 1.2中,我们现在有了这个isInitialized方法.当我在声明lateinit属性的类中执行此操作时,它可以正常工作.但是当我尝试从另一个类调用它时,我得到以下警告:

此时无法访问'lateinit var foo:Bar'的后备字段

我的模型类(比方说Person)是用Java编写的.
其他两个类(比如说Test1Test2)是用Kotlin编写的

例:

class Test1 {
    lateinit var person: Person

    fun method() {
        if (::person.isInitialized) {
            // This works
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

-

class Test2 {
    lateinit var test1: Test1

    fun method() {
        if (test1::person.isInitialized) {
            // Error
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有机会让这个工作吗?

我目前的解决方法是在Test1中创建一个isInitializedperson属性返回的方法.

fun isPersonInitialized(): Boolean = ::person.isInitialized

//in Test2:
if (test1.isPersonInitialized()) {
    // Works
}
Run Code Online (Sandbox Code Playgroud)

Aut*_*pps 33

接受的答案描述的约束的一个非常简单的解决方法如下:

class LateClass {
    lateinit var thing: Thing
    fun isThingInitialized() = ::thing.isInitialized
}

class Client {
    val lateClass = LateClass()
    ... things happen ...
    if (lateClass.isThingInitialized() {
        // do stuff with lateClass.thing, safely
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 非常好,优雅。转换为属性。val isThingInitialized:Boolean = :: thing.isInitialized (2认同)
  • `val isThingInitialized: Boolean = ::thing.isInitialized` 将始终为 false,因为仅预先计算一次。您可以像此解决方案中那样创建一个函数,或者创建一个惰性字段: `val isThingInitialized: Boolean by lazy { ::thing.isInitialized }` (2认同)
  • @TejasviHegde 仅当您为其设置 getter 时,使用属性才能成功。 (2认同)

Sat*_*tli 8

我的版本作为 Kotlin 属性。

class LateClass {
    lateinit var thing: Thing
    val isThingInitialized get() = this::thing.isInitialized 
}
Run Code Online (Sandbox Code Playgroud)


Rag*_*dra 7

根据文档

此检查仅适用于可按词法访问的属性,即以相同类型或外部类型之一声明,或在同一文件的顶级声明的属性。

这就是为什么您不能在主要功能中进行检查的原因。

  • 在 kotlin v1.3.+ 中仍应考虑这一点:) (3认同)