У меня есть программа на Java, и я получаю исключение NullPointerException, и я видел другие вопросы, но они от людей с другими программами, и это не работает для моей программы, и я хочу оставить вам здесь 2000 строк моей программы, чтобы вы могли решить проблема для меня но люди не пускают.
Смотри, моя программа такая
Object a = null;
// 500 líneas de código
// Dentro de un bucle, dentro de un if, dentro de un for...
a = algunaFuncionDeMilLineasQueNoTeVoyAMostrar(
parámetrosDeLosQueNoTeDiréElValor)
// Cerrando for, cerrando if, cerrando bucle.
// Otras 500 líneas de código
// Una de estas líneas lanza el NPE, pero no te diré cuál.
a.toString();
z.hazAlgunaCosa();
x.haxY().hazM().cuantoFaltaParaLasVacaciones().andaMiraUnPatoQuePasaPorAhi();
Это не правильно? Почему нет универсального решения для исключений NullPointerException (NPE), если они случаются так часто?
Решение (барабанная дробь)...
Не используйте методы или свойства пустой переменной или выражения.
Если у вас есть строка:
и бросает вам NPE, это то, что когда вы его выполняете
p
, это стоитnull
. Перед выполнением строки убедитесь, что оно имеет ненулевое значение.Это все...
Нет необходимости повторять один и тот же вопрос миллион раз, даже если программа разная.Ясно, не так ли? Как и было обещано, решено навсегда.
Если ваша строка похожа на
точно так же, если какой-либо из методов возвращает null , при попытке вызвать соответствующий метод JVM выдаст исключение NullPointerException. Единственная разница с предыдущим примером заключается в том, что JVM покажет вам только ошибку в строке, и вам придется выяснить, на каком шаге появляется нуль .
Это немного изменилось по сравнению с версией 14 языка, в которой появилась возможность сообщать JVM, чтобы она давала нам более подробные сообщения о коде, выдающем исключение 1 . Эта опция по умолчанию отключена, поэтому для ее включения необходимо включить параметр командной строки JVM
-XX:+ShowCodeDetailsInExceptionMessages
при выполнении программы.И теперь, когда кто-то протестует: «Но это не помогает мне с моей проблемой, что я получаю исключение NullPointerException в своей программе, которую я пишу здесь 2 »?
Ответ: Если есть исключение NullPointerException, ваша проблема не в исключении NullPointerException.
Программист обязан знать, как работает его программа и как организованы данные. Это не тот вопрос, который можно загрузить в StackOverflow. Если у вас есть NPE, вы находитесь в одном (или нескольких) из этих случаев:
Типичный случай - сказать "в этом методе это
a
может быть 1 или 2" и сделатьВаша проблема в том, что это
a
стоит того, чего вы не ожидали, вкупе с тем, что вы не программируете оборонительно и не контролируете значения. Отладьте свою программу, чтобы исправить значениеa
, добавьте такое,default
которое вызывает исключение, когда значение является неожиданным.У вас такой сложный метод, что вы не знаете, когда присваиваются значения ссылке. Измените свою программу так, чтобы ее было легко читать и понимать. Не уподобляйтесь старым элбонианцам, которые говорили: «Писать легко, мы надеемся, что когда-нибудь научимся читать». Если вы хотите проверить, работает ли ваша программа так, как вы ожидаете, используйте инструмент отладки или создайте сообщения журнала, чтобы вы могли проверить ее работу. Если вам нужен кто-то из Интернета, чтобы объяснить, как работает ваша программа, рассмотрите другую профессию.
У вас проблема с API. Вы выполнили все шаги, упомянутые выше, и в конце концов обнаружили, что причина происхождения в том, что вы звоните,
java.util.Collections.toArray()
и он возвращает значениеnull
. Проверьте документацию метода, проверьте параметры, которые вы передаете, и т. д. Если вы все еще не можете найти решение, поздравляем!!!! Теперь у вас есть вопрос, который подходит для SO («Почему java.util.Collections.toArray() возвращает мне null?»)У вас есть вектор, который вы каким-то образом инициализировали, но никогда не инициализировали его внутри. Это
tipo1 vector[] = new tipo1[n];
не означает, что вектор будет волшебным образом заполнен объектами типа 1 . Вы должны сделать New type1 для каждой позиции вектора.Еще одно замечание о массивах
Так как путаница возникает довольно часто, мы будем настаивать на последнем пункте:
При создании массива объектов массив создается, но объекты не создаются . После первой строки кода выше у вас есть объект myArray (вы можете сделать myArray.length ), но этот объект содержит только 10 ссылок ( myArray[0] , myArray[1] ...) на null ; экземпляры, на которые они указывают, еще не назначены. Если этим ссылкам не назначен экземпляр, то попытка вызвать методы или атрибуты вызовет исключение NullPointerException.
1 Для получения дополнительной информации см. JEP 358: Helpful NullPointerExceptions .
2 Далее следует тысяча строк кода, причем, разумеется, даже без указания, на какой строке запускается NPE.
Если вы подозреваете, что переменная с
null
y выдаст ошибку,NullPointerException
решите ее, добавив блок try-catch , и он устранит ошибку. Вы можете дать своим объектам a,new Object
и он загрузит ихnull
в виде строки в ваше приложение, чтобы вы могли видеть, какой объект прерывает поток вашей программы.Вы также можете прочитать предупреждения в коде, они очень помогают.
Как насчет доброго дня, конечно есть решение для обработки NPE и это не обязательно обработка исключения, я рекомендую вам использовать шаблон проектирования Null Object Pattern , это сделает ваш код более надежным, и вы будете иметь контроль этого типа ошибок, тем самым предотвращая прерывание программы во время выполнения.
Вот UML-диаграмма:
Реализация действительно проста. Я рекомендую вам не проверять object.something.something != null и не злоупотреблять обобщенным try/catch, потому что это не решит вашу проблему, они будут только контролировать ее, но основная проблема будет продолжать существовать.
Ваше здоровье!!!
Часть вашей проблемы, вероятно, заключается в том, что вы
funciondeMilLineas
выполняете очень длинные и очень запутанные функции, в которых легко сделать ошибки. Простое эмпирическое правило относительно того, какой длины должна быть функция, заключается в том, что ее можно просмотреть на экране. На моем мониторе около 40 строк. Вы можете играть с размером буквы, но более или менее это длина.Нелегко научиться разбивать код на функции. То, что я прочитал по теме, которая мне больше всего понравилась, было в книге Роберта С. Мартина под названием « Чистый код », в которой есть целая глава о функциях. Что там написано:
Очевидно, немного сложно понять, что это значит, и применить это на практике. Но я думаю, что стоит изучить это, прежде чем создавать программы, которые работают, но затем слишком сложны для расширения.
Дело в том
NullPointerException
, что вы не инициализировали никаких ссылок на Java. Упрощая это до зверя, вы где-то что-new
то упускаете.PS: Если вы действительно доберетесь до функции в тысячу строк, не сомневайтесь, что она неверна. Это надо разделить.
Если бы я мог внести что-то, что я так не думаю, потому что они достаточно хорошо ответили выше (теперь я отдам голос), я бы добавил:
-если это параметр, вы должны проверить его перед использованием. -если это результат, используйте опции
Пример:
Вы можете реализовать a
try{}catch(NullPointerException){}
, поскольку, как говорится, он перехватывает все поля, которые имеют значение null, или убедитесь, что они не равны нулю при их вызове. вы можете реализовать метод, который получает объект и проверяет, что он не равен нулюили лучше убедиться при программировании, что он уже содержит ссылку или что он инициализирован.
Есть один вариант, который, похоже, мало используется для смягчения проблемы NullPointerExceptions, и это
java.util.Objects
. Этот класс, присутствующий в JDK начиная с Java 7, содержит несколько статических методов, которые могут сильно помочь в обработке нулей.Самый простой — это просто проверить, является ли переменная нулевой или нет. Обычно это делается:
Меня всегда немного беспокоило использование ==, потому что обычно это неправильный способ сравнения объектов (хотя в этом случае он работает так, как ожидалось). С классом объектов мы можем сделать:
Если мы также импортируем объекты статически:
Это намного яснее, лаконичнее и элегантнее. Кроме того, это еще лучше при использовании в потоках, например в фильтре:
Еще один классный метод из класса Objects — это requireNonNullElse() (хотя этот метод присутствует только начиная с Java 9). Обычно мы делаем что-то подобное, если хотим присвоить переменную, подтверждающую, что она не равна нулю:
(здесь мы также могли бы использовать тернарный оператор, но это было бы похоже). С объектами мы могли бы сделать:
Есть еще одна похожая версия, которая принимает поставщика в качестве второго аргумента:
Какая разница между двумя? как работает Java, requireNonNullElse() будет оценивать второй аргумент, даже если первый аргумент не равен нулю и не должен его возвращать. Поэтому, если этот второй аргумент сложно создать, он занимает много памяти или много обработки, вы можете использовать requireNonNullElseGet() и создать объект в теле поставщика. Поскольку результат лямбда-выражения не будет оцениваться до тех пор, пока он действительно не понадобится, мы спасаем себя от создания чего-то, что не будет использоваться.
В классе Objects есть еще несколько методов, которые помогают предотвратить NullPointerExceptions, но эти кажутся мне наиболее важными. Вы можете проверить документацию здесь: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Objects.html .
Это легко решается, проверка. Говорят, что исключения NullPointerException генерируются ошибками программиста, если вы знаете, что метод может возвращать объект или должен работать с объектом, просто поставьте: