Ненулевое значение в Kotlin производит nullpointerexception
У меня есть массив ненулевых значений, как это:
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 ненулевых объектов иногда содержит нулевой объект. Я пытаюсь понять, как это может произойти. Я ожидаю, что Kotlin будет жаловаться, если к ArrayList будет добавлено ненулевое значение, и, конечно, я не уверен, как это вообще может произойти, поскольку я помещаю в массив только ненулевые значения. Проблемы с потоками? Любые идеи приветствуются:) Спасибо.
2 ответа
Используйте Collections.synchronizedList(ArrayList()). Единственное объяснение, которое я могу придумать, - это проблема с потоками, которая устраняется путем синхронизации коллекции.
Из документа , связанного с нулевой безопасностью, проблема может быть вызвана:
Неинициализированный
this
доступный в конструкторе, передается и где-то используется («утечка этого»).
Другими словами, исключение NullPointerException описывает объект как еще не инициализированный. Только после инициализации объект на стороне вызывающего объекта не равен нулю.
Я видел исключение, созданное в AsyncTask. Вы можете проверить, может ли быть какой-то асинхронный вызов задачи
dog.P()
до его инициализации.