检查 null 状态时的 Kotlin null 指针

Kotlin null pointer when checking for null state

提问人:user1743524 提问时间:3/29/2023 更新时间:3/29/2023 访问量:164

问:

我有一个简单的 null 检查导致异常的代码块

科特林。UninitializedPropertyAccessException:lateinit 属性 currentJob 尚未初始化 在 com.plcoding.posterpalfeature.ui.MainViewModel.getCurrentJob(MainViewModel.kt:40) 在 com.plcoding.posterpalfeature.ui.MainViewModel.getJobsListFromApi(MainViewModel.kt:284)

我试过这个-->

 with(currentJob){
            if (this == null) {
                currentJob = jobsDataList.get(0) //maybe replace with accepted jobs depending on how details is implemented
            }
            else {
                //update the current job using job id to get fresh object
                currentJob = jobsDataList.filter {
                    it.job.job_id == currentJob.job.job_id
                }.get(0)
            }//should only ever be single object
        }

if (currentJob == null) {
                currentJob = jobsDataList.get(0) //maybe replace with accepted jobs depending on how details is implemented
            }
            else {
                //update the current job using job id to get fresh object
                currentJob = jobsDataList.filter {
                    it.job.job_id == currentJob.job.job_id
                }.get(0)
            }

和 when 语句,它们都抛出相同的异常

这是我的变量

lateinit var currentJob:工作PW

有什么想法吗?这真的很奇怪。我正在考虑提出错误报告,但我不确定在哪里做。

Android kotlin null nullpointerexception kotlin-lateinit

评论

0赞 ninhnau19 3/29/2023
在 StackTrace 中,我看到它指向第 40 行和第 284 行。这条线到底是什么?
0赞 Code-Apprentice 3/29/2023
编辑您的问题以显示一个最小的可重现示例,我们可以复制/粘贴并自行运行以获得您提出的相同错误。

答:

1赞 ninhnau19 3/29/2023 #1

在使用 lateinit var 变量之前,您需要设置它的值。

要检查变量是否已启动,您可以使用以下命令进行检查:

this::currentJob.isInitialized
2赞 Cililing 3/29/2023 #2

这是因为您尝试访问(通过)未初始化的 lateinit 变量。== null

让我们看看文档告诉我们什么:

例如,可以通过依赖项注入或单元测试的设置方法初始化属性。在这些情况下,不能在构造函数中提供非 null 初始值设定项,但在引用类主体内的属性时仍希望避免 null 检查。

因此,这样的代码总是抛出异常:

class Test {

    lateinit var lateinitAny: Any

    @Test
    fun test() {
        if (lateinitAny == null) { // throws kotlin.UninitializedPropertyAccessException
            println()
        }
    }
}

因此,您的情况看起来像是 lateinit 属性的无效使用。这些变量通常由 DI 框架等处理。在你的例子中,你只需要使用可为空的属性:

var currentJob: Job? = null

然后你的代码应该可以正常工作。 但是,您仍然可以检查该属性是否由 初始化。但是,就像我说的,lateinit 是为“标准”变量用法以外的其他东西而设计的。this::lateinitAny.isInitialized

编号: https://kotlinlang.org/docs/properties.html#late-initialized-properties-and-variables