在Kotlin中非空值导致空指针异常

3

我是一名翻译助手,以下是您需要的翻译内容。涉及IT技术相关的非空值数组如下:

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)

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

你的代码从来没有展示过你调用Dog.P()的实例。如果你用假设的代码替换了你的代码,请不要这样做。请发布你的真实代码,并且提供更多的代码内容。 - undefined
这个跟踪来自分析服务,并且发生在一个真实的客户设备上。方法名被混淆了,但是它是正确的调用。我无法在我的测试实验室中重现这个问题,否则我会发布完整的堆栈跟踪信息。 - undefined
那就无法帮助了。大多数崩溃报告服务都允许您上传混淆应用程序的映射文件,以获取正确的堆栈跟踪信息。 - undefined
就像我之前说的那样,我将代码与堆栈跟踪进行了无歧义的匹配。我不确定在堆栈跟踪中还有什么其他可以帮助的内容。从后台线程来看,它已经尽可能完整了。 - undefined
我对一个通用的想法感兴趣(不仅限于代码),关于在Kotlin中声明为非空值的ArrayList可能出现null值的原因。例如,两个线程同时访问数组并添加新元素。第三个线程在另一个线程更新数组时读取该数组时,是否可能得到一个null元素? - undefined
1
嗨,我实际上遇到了完全相同的问题。对于这个问题的进展非常好奇。 - undefined
2个回答

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

0

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

在构造函数中传递并使用了未初始化的this(即“泄漏的this”)。

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接