Kotlin 中的非 null 值产生 nullpointerexception

Non-null value in Kotlin produces nullpointerexception

提问人:alexbtr 提问时间:10/27/2018 最后编辑:TheWandereralexbtr 更新时间:11/25/2021 访问量:1575

问:

我有一个不可为空的值数组,如下所示:

private val dogs = ArrayList{Dog}() // replace {} with <>

它是这样填充的:

val dog = Dog()  
dog.name = “bob”  
dogs.add(dog)  

根据代码流的不同,最多有 3 种不同的方法可以像这样填充它。 填充数组后,将对其进行处理:

if (dogs.size > 0) {  
    Collections.sort(dogs, Dog.comparator)  
    for (i in dogs.indices) {  
        val dog = dogs[i]  
        dog.bark()  
    }  
}

所有这些都是在 AsyncTask doInbackground 中完成的。

调用dog.bark()时,我间歇性地出现以下异常:

致命异常:java.lang.RuntimeException 执行 doInBackground() 时出错

Caused by java.lang.NullPointerException: Attempt to invoke virtual method com.myname.model.Dog.P()' on a null object reference
       at com.myname.util.RunnableAsync.doInBackground(SourceFile:5)
       at android.os.AsyncTask$2.call(AsyncTask.java:333)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

简而言之,非 null 对象的 ArrayList 有时包含一个 null 对象。 我试图弄清楚这是怎么发生的。如果将非 null 值添加到 ArrayList 中,我希望 Kotlin 会抱怨,当然我不确定这首先是如何发生的,因为我只将非 null 值放入数组中。线程问题?欢迎任何想法:) 谢谢。

android arraylist android-asynctask nullpointerexception kotlin-null-safety

评论

0赞 TheWanderer 10/27/2018
您的代码永远不会显示您调用 .如果将代码替换为假设代码,请不要这样做。发布您的实际代码,而且比这更多。Dog.P()
0赞 alexbtr 10/27/2018
此跟踪来自分析服务,它发生在真实的客户设备上。方法名称被模糊处理,但它是正确的调用。我无法在我的测试实验室中重现该问题,或者我会发布确切的堆栈跟踪。
0赞 TheWanderer 10/27/2018
那是不可能的。大多数崩溃报告服务都允许您上传混淆应用的映射文件,以获取正确的堆栈跟踪。
0赞 alexbtr 10/27/2018
正如我之前所说,我将代码与堆栈跟踪匹配,没有任何歧义。我不确定在堆栈跟踪中还有什么帮助。它从后台线程中尽可能完整。
1赞 WenChao 12/11/2018
嗨,我实际上遇到了完全相同的问题。很好奇这是怎么回事?

答:

0赞 alexbtr 12/12/2018 #1

使用 Collections.synchronizedList(ArrayList())。 我能想到的唯一解释是线程问题,该问题通过同步集合来解决。

0赞 zwh 11/25/2021 #2

从与空安全相关的文档中,该问题可能是由以下原因引起的:

构造函数中未初始化的可用被传递并在某处使用(“泄漏此”)。this

换句话说,NullPointerException 将对象描述为尚未初始化。只有在初始化后,调用方端的对象才为非 null。

我在AsyncTask中看到了异常。您可以在初始化之前检查是否存在一些异步任务调用。dog.P()