我想知道是否有方法检查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
    }
}

当前回答

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

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

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

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

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

其他回答

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

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

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

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

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

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

lateinit var file: File    

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

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

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

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

kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized

字节码说。。。等等。。

public final static synthetic access$getClientKeypair$p(Lcom/takharsh/ecdh/MainActivity;)Ljava/security/KeyPair;

`L0
LINENUMBER 11 L0
ALOAD 0
GETFIELD com/takharsh/ecdh/MainActivity.clientKeypair : Ljava/security/KeyPair;
DUP
IFNONNULL L1
LDC "clientKeypair"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V
    L1
ARETURN

L2级本地变量$this Lcom/takharact/edch/MainActivity;10升20最大堆栈=2最大局部值=1

Kotlin为同一实例创建一个额外的本地变量,并检查它是否为null,如果为null,则抛出“throwUninitializedPropertyAccessException”,否则返回本地对象。以上字节码在此解释解决方案从kotlin 1.2开始,它允许检查lateinit var是否已初始化或未使用.isInitized

接受的答案在Kotlin 1.3+中给了我一个编译器错误,我必须在前面明确提到这个关键字::。以下是工作代码。

lateinit var file: File

if (this::file.isInitialized) {

    // file is not null
}

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

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