我想知道是否有方法检查lateinit变量是否已初始化。例如:

class Foo() {

    private lateinit var myFile: File

    fun bar(path: String?) {
        path?.let { myFile = File(it) }
    }

    fun bar2() {
        myFile.whateverMethod()
        // May crash since I don't know whether myFile has been initialized
    }
}

当前回答

正在检查lateinit变量

要检查lateinit变量是否已初始化,只需在属性引用::上使用.isInitized布尔值。

if (foo::bar.isInitialized) {
    println(foo.bar)
}

Playground Kotlin的代码可能如下:

fun main() {        
    var declarative = Declarative()
    declarative.checkLateInit()
}

class Declarative {   
    lateinit var compose: String

    fun checkLateInit() {            
        println(this::compose.isInitialized)
        compose = "Jetpack Compose 1.2"
      
        if (this::compose.isInitialized) {
            println(this.compose)
        }
    }
}

// Result:

// false
// Jetpack Compose 1.2

此检查仅适用于以词汇方式可访问的财产,即在同一类型或其中一个外部类型中声明的属性,或在同一文件的顶层声明的属性。

其他回答

尝试使用它,如果它未初始化,您将收到UninitializedPropertyAccessException。

lateinit专门用于在构造之后但在实际使用之前初始化字段的情况(大多数注入框架使用的模型)。如果这不是您的用例,lateinit可能不是正确的选择。

编辑:根据你想要做的事情,这样做会更好:

val chosenFile = SimpleObjectProperty<File?>
val button: Button

// Disables the button if chosenFile.get() is null
button.disableProperty.bind(chosenFile.isNull())

正在检查lateinit变量

要检查lateinit变量是否已初始化,只需在属性引用::上使用.isInitized布尔值。

if (foo::bar.isInitialized) {
    println(foo.bar)
}

Playground Kotlin的代码可能如下:

fun main() {        
    var declarative = Declarative()
    declarative.checkLateInit()
}

class Declarative {   
    lateinit var compose: String

    fun checkLateInit() {            
        println(this::compose.isInitialized)
        compose = "Jetpack Compose 1.2"
      
        if (this::compose.isInitialized) {
            println(this.compose)
        }
    }
}

// Result:

// false
// Jetpack Compose 1.2

此检查仅适用于以词汇方式可访问的财产,即在同一类型或其中一个外部类型中声明的属性,或在同一文件的顶层声明的属性。

Kotlin 1.2中有一个lateinit改进,允许直接检查lateinit变量的初始化状态:

lateinit var file: File    

if (this::file.isInitialized) { ... }

请参阅JetBrains博客上的公告或KEEP提案。

更新:Kotlin 1.2已经发布。您可以在这里找到lateinit增强功能:

检查lateinit变量是否已初始化Lateinit顶级财产和局部变量

使用.isInitized属性可以检查lateinit变量的初始化状态。

if (::file.isInitialized) {
    // File is initialized
} else {
    // File is not initialized
}

如果在一个类中有一个lateinit属性,并且需要检查它是否是从另一个类初始化的

if(foo::file.isInitialized) // this wouldn't work

我找到的解决方法是创建一个函数来检查属性是否已初始化,然后可以从任何其他类调用该函数。

例子:

class Foo() {

    private lateinit var myFile: File

    fun isFileInitialised() = ::file.isInitialized
}

 // in another class
class Bar() {

    val foo = Foo()

    if(foo.isFileInitialised()) // this should work
}