Java application error nullpointerexception



Как понять NullPointerException

Эта простая статья скорее для начинающих разработчиков Java, хотя я нередко вижу и опытных коллег, которые беспомощно глядят на stack trace, сообщающий о NullPointerException (сокращённо NPE), и не могут сделать никаких выводов без отладчика. Разумеется, до NPE своё приложение лучше не доводить: вам помогут null-аннотации, валидация входных параметров и другие способы. Но когда пациент уже болен, надо его лечить, а не капать на мозги, что он ходил зимой без шапки.

Итак, вы узнали, что ваше приложение упало с NPE, и у вас есть только stack trace. Возможно, вам прислал его клиент, или вы сами увидели его в логах. Давайте посмотрим, какие выводы из него можно сделать.

NPE может произойти в трёх случаях:

  1. Его кинули с помощью throw
  2. Кто-то кинул null с помощью throw
  3. Кто-то пытается обратиться по null-ссылке

Во втором и третьем случае message в объекте исключения всегда null, в первом может быть произвольным. К примеру, java.lang.System.setProperty кидает NPE с сообщением «key can’t be null», если вы передали в качестве key null. Если вы каждый входной параметр своих методов проверяете таким же образом и кидаете исключение с понятным сообщением, то вам остаток этой статьи не потребуется.

Обращение по null-ссылке может произойти в следующих случаях:

  1. Вызов нестатического метода класса
  2. Обращение (чтение или запись) к нестатическому полю
  3. Обращение (чтение или запись) к элементу массива
  4. Чтение length у массива
  5. Неявный вызов метода valueOf при анбоксинге (unboxing)

Важно понимать, что эти случаи должны произойти именно в той строчке, на которой заканчивается stack trace, а не где-либо ещё.

Рассмотрим такой код:

Откуда-то был вызван метод handle с какими-то параметрами, и вы получили:

В чём причина исключения — в f, d или d.val? Нетрудно заметить, что f в этой строке вообще не читается, так как метод format статический. Конечно, обращаться к статическому методу через экземпляр класса плохо, но такой код встречается (мог, например, появиться после рефакторинга). Так или иначе значение f не может быть причиной исключения. Если бы d был не null, а d.val — null, тогда бы исключение возникло уже внутри метода format (в девятой строчке). Аналогично проблема не могла быть внутри метода getValue, даже если бы он был сложнее. Раз исключение в пятнадцатой строчке, остаётся одна возможная причина: null в параметре d.

Вот другой пример:

Снова вызываем метод handle и получаем

Теперь метод format нестатический, и f вполне может быть источником ошибки. Зато s не может быть ни под каким соусом: в девятой строке уже было обращение к s. Если бы s было null, исключение бы случилось в девятой строке. Просмотр логики кода перед исключением довольно часто помогает отбросить некоторые варианты.

С логикой, конечно, надо быть внимательным. Предположим, условие в девятой строчке было бы написано так:

Теперь в самой строчке обращения к полям и методам s нету, а метод equals корректно обрабатывает null, возвращая false, поэтому в таком случае ошибку в двенадцатой строке мог вызвать как f, так и s. Анализируя вышестоящий код, уточняйте в документации или исходниках, как используемые методы и конструкции реагируют на null. Оператор конкатенации строк +, к примеру, никогда не вызывает NPE.

Вот такой код (здесь может играть роль версия Java, я использую Oracle JDK 1.7.0.45):

Вызываем метод dump, получаем такое исключение:

В параметре pw не может быть null, иначе нам не удалось бы войти в метод print. Возможно, null в obj? Легко проверить, что pw.print(null) выводит строку «null» без всяких исключений. Пойдём с конца. Исключение случилось здесь:

В строке 473 возможна только одна причина NPE: обращение к методу length строки s. Значит, s содержит null. Как так могло получиться? Поднимемся по стеку выше:

В метод write передаётся результат вызова метода String.valueOf. В каком случае он может вернуть null?

Единственный возможный вариант — obj не null, но obj.toString() вернул null. Значит, ошибку надо искать в переопределённом методе toString() нашего объекта MyObject. Заметьте, в stack trace MyObject вообще не фигурировал, но проблема именно там. Такой несложный анализ может сэкономить кучу времени на попытки воспроизвести ситуацию в отладчике.

Не стоит забывать и про коварный автобоксинг. Пусть у нас такой код:

И такое исключение:

На первый взгляд единственный вариант — это null в параметре obj. Но следует взглянуть на класс MyContainer:

Читайте также:  No boot disk has been detected or the disk has failed как исправить error

Мы видим, что getCount() возвращает Integer, который автоматически превращается в int именно в третьей строке TestNPE.java, а значит, если getCount() вернул null, произойдёт именно такое исключение, которое мы видим. Обнаружив класс, подобный классу MyContainer, посмотрите в истории системы контроля версий, кто его автор, и насыпьте ему крошек под одеяло.

Помните, что если метод принимает параметр int, а вы передаёте Integer null, то анбоксинг случится до вызова метода, поэтому NPE будет указывать на строку с вызовом.

В заключение хочется пожелать пореже запускать отладчик: после некоторой тренировки анализ кода в голове нередко выполняется быстрее, чем воспроизведение трудноуловимой ситуации.

Источник

Ошибка java.lang.nullpointerexception, как исправить?

Ряд пользователей (да и разработчиков) программных продуктов на языке Java могут столкнуться с ошибкой java.lang.nullpointerexception (сокращённо NPE), при возникновении которой запущенная программа прекращает свою работу. Обычно это связано с некорректно написанным телом какой-либо программы на Java, требуя от разработчиков соответствующих действий для исправления проблемы. В этом материале я расскажу, что это за ошибка, какова её специфика, а также поясню, как исправить ошибку java.lang.nullpointerexception.

Что это за ошибка java.lang.nullpointerexception

Появление данной ошибки знаменует собой ситуацию, при которой разработчик программы пытается вызвать метод по нулевой ссылке на объект. В тексте сообщения об ошибке система обычно указывает stack trace и номер строки, в которой возникла ошибка, по которым проблему будет легко отследить.

Что в отношении обычных пользователей, то появление ошибки java.lang.nullpointerexception у вас на ПК сигнализирует, что у вас что-то не так с функционалом пакетом Java на вашем компьютере, или что программа (или онлайн-приложение), работающие на Java, функционируют не совсем корректно. Если у вас возникает проблема, при которой Java апплет не загружен, рекомендую изучить материал по ссылке.

Как исправить ошибку java.lang.nullpointerexception

Как избавиться от ошибки java.lang.nullpointerexception? Способы борьбы с проблемой можно разделить на две основные группы – для пользователей и для разработчиков.

Для пользователей

Если вы встретились с данной ошибкой во время запуска (или работы) какой-либо программы (особенно это касается minecraft), то рекомендую выполнить следующее:

  1. Переустановите пакет Java на своём компьютере. Скачать пакет можно, к примеру, вот отсюда;
  2. Переустановите саму проблемную программу (или удалите проблемное обновление, если ошибка начала появляться после такового);
  3. Напишите письмо в техническую поддержку программы (или ресурса) с подробным описанием проблемы и ждите ответа, возможно, разработчики скоро пофиксят баг.
  4. Также, в случае проблем в работе игры Майнкрафт, некоторым пользователям помогло создание новой учётной записи с административными правами, и запуск игры от её имени.

Для разработчиков

Разработчикам стоит обратить внимание на следующее:

  1. Вызывайте методы equals(), а также equalsIgnoreCase() в известной строке литерала, и избегайте вызова данных методов у неизвестного объекта;
  2. Вместо toString() используйте valueOf() в ситуации, когда результат равнозначен;
  3. Применяйте null-безопасные библиотеки и методы;
  4. Старайтесь избегать возвращения null из метода, лучше возвращайте пустую коллекцию;
  5. Применяйте аннотации @Nullable и @NotNull;
  6. Не нужно лишней автоупаковки и автораспаковки в создаваемом вами коде, что приводит к созданию ненужных временных объектов;
  7. Регламентируйте границы на уровне СУБД;
  8. Правильно объявляйте соглашения о кодировании и выполняйте их.

Источник

Что такое NullPointerException и как это исправить

Довольно часто при разработке на Java программисты сталкиваются с NullPointerException, появляющимся в самых неожиданных местах. В этой статье мы разберёмся, как это исправить и как стараться избегать появления NPE в будущем.

NullPointerException – что это такое?

NullPointerException (оно же NPE) это исключение, которое выбрасывается каждый раз, когда вы обращаетесь к методу или полю объекта по ссылке, которая равна null. Разберём простой пример:

Здесь на первой строке мы объявили переменную типа Integer и присвоили ей значение null (то есть переменная не указывает ни на какой существующий объект).
На второй строке мы обращаемся к методу toString переменной n1. Так как переменная равна null, метод не может выполниться (переменная не указывает ни на какой реальный объект), генерируется исключение NullPointerException:

Как исправить NullPointerException

В нашем простейшем примере мы можем исправить NPE, присвоив переменной n1 какой-либо объект (то есть не null):

Теперь не будет исключения при доступе к методу toString и наша программа отработает корректно.

Если ваша программа упала из-за исключение NullPointerException (или вы перехватили его где-либо), вам нужно определить по стектрейсу, какая строка исходного кода стала причиной появления этого исключения. Иногда причина локализуется и исправляется очень быстро, в нетривиальных случаях вам нужно определять, где ранее по коду присваивается значение null.

Иногда вам требуется использовать отладку и пошагово проходить программу, чтобы определить источник NPE.

Как избегать исключения NullPointerException

Существует множество техник и инструментов для того, чтобы избегать появления NullPointerException. Рассмотрим наиболее популярные из них.

Проверяйте на null все объекты, которые создаются не вами

Если объект создаётся не вами, иногда его стоит проверять на null, чтобы избегать ситуаций с NullPinterException. Здесь главное определить для себя рамки, в которых объект считается «корректным» и ещё «некорректным» (то есть невалидированным).

Не верьте входящим данным

Если вы получаете на вход данные из чужого источника (ответ из какого-то внешнего сервиса, чтение из файла, ввод данных пользователем), не верьте этим данным. Этот принцип применяется более широко, чем просто выявление ошибок NPE, но выявлять NPE на этом этапе можно и нужно. Проверяйте объекты на null. В более широком смысле проверяйте данные на корректность, и консистентность.

Возвращайте существующие объекты, а не null

Если вы создаёте метод, который возвращает коллекцию объектов – не возвращайте null, возвращайте пустую коллекцию. Если вы возвращаете один объект – иногда удобно пользоваться классом Optional (появился в Java 8).

Заключение

В этой статье мы рассказали, как исправлять ситуации с NullPointerException и как эффективно предотвращать такие ситуации при разработке программ.

Источник

Java NullPointerException

Last Updated: October 1, 2022

Java NullPointerException (NPE) is an unchecked exception and extends RuntimeException . NullPointerException doesn’t force us to use a try-catch block to handle it.

NullPointerException has been very much a nightmare for most Java developers. It usually pop up when we least expect them.

I have also spent a lot of time while looking for reasons and the best approaches to handle null issues. I will be writing here some of the best practices followed industry-wise, sharing some expert talks and my own learning over time.

1. Why NullPointerException Occur in the Code?

NullPointerException is a runtime condition where we try to access or modify an object which has not been initialized yet. It essentially means that the object’s reference variable is not pointing anywhere and refers to nothing or ‘null’.

In the given example, String s has been declared but not initialized. When we try to access it in the next statement s.toString() , we get the NullPointerException.

2. Common Places Where NPEs Occur?

Well, NullPointerException can occur anywhere in the code for various reasons but I have prepared a list of the most frequent places based on my experience.

  1. Invoking methods on an object which is not initialized
  2. Parameters passed in a method are null
  3. Calling toString() method on object which is null
  4. Comparing object properties in if block without checking null equality
  5. Incorrect configuration for frameworks like Spring which works on dependency injection
  6. Using synchronized on an object which is null
  7. Chained statements i.e. multiple method calls in a single statement

This is not an exhaustive list. There are several other places and reasons also. If you can recall any such other, please leave a comment. it will help others also.

3. Best Ways to Avoid NullPointerException

3.1. Use Ternary Operator

Ternary operator results in the value on the left-hand side if not null else right-hand side is evaluated. It has syntax like :

If the expression is evaluated as true then the entire expression returns value1 otherwise value2.

It is more like an if-else construct but it is more effective and expressive. To prevent NullPointerException (NPE), use this operator like the below code:

3.2. Use Apache Commons StringUtils for String Operations

Apache Commons Lang is a collection of several utility classes for various kinds of operation. One of them is StringUtils.java.

Use the following methods for better handling the strings in your code.

3.3. Fail Fast Method Arguments

We should always do the method input validation at the beginning of the method so that the rest of the code does not have to deal with the possibility of incorrect input.

Therefore if someone passes in a null as the method argument, things will break early in the execution lifecycle rather than in some deeper location where the root problem will be rather difficult to identify.

Aiming for fail-fast behavior is a good choice in most situations.

3.4. Consider Primitives instead of Objects

A null problem occurs where object references point to nothing. So it is always safe to use primitives. Consider using primitives as necessary because they do not suffer from null references.

All primitives have some default value assigned to them so be careful.

3.5. Carefully Consider Chained Method Calls

While chained statements are nice to look at in the code, they are not NPE friendly.

A single statement spread over several lines will give you the line number of the first line in the stack trace regardless of where it occurs.

These kind of chained statement will print only “NullPointerException occurred in line number xyz”. It really is hard to debug such code. Avoid such calls if possible.

3.6. Use valueOf() in place of toString()

If we have to print the string representation of any object, then consider not using toString() method. This is a very soft target for NPE.

Instead use String.valueOf(object). Even if the object is null in this case, it will not give an exception and will print ‘ null ‘ to the output stream.

3.7. Avoid Returning null from Methods

An awesome tip to avoid NPE is to return empty strings or empty collections rather than null. Java 8 Optionals are a great alternative here.

Do this consistently across your application. You will note that a bucket load of null checks becomes unneeded if you do so.

Users of the above method, even if they missed the null check, will not see the ugly NPE.

3.8. Discourage Passing of null as Method Arguments

I have seen some method declarations where the method expects two or more parameters. If one parameter is passed as null, then also method works in a different manner. Avoid this.

Instead, we should define two methods; one with a single parameter and the second with two parameters.

Make parameters passing mandatory. This helps a lot when writing application logic inside methods because you are sure that method parameters will not be null; so you don’t put unnecessary assumptions and assertions.

3.9. Call equals() on ‘Safe’ Non-null Stringd

Instead of writing the below code for string comparison

write the above code like given below example. This will not cause in NPE even if param is passed as null.

4. NullPointerException Safe Operations

4.1. instanceof Operator

The instanceof operator is NPE safe. So, instanceof null always returns false .

This operator does not cause a NullPointerException. You can eliminate messy conditional code if you remember this fact.

4.2. Accessing static Members of a Class

If you are dealing with static variables or static methods then you won’t get a null pointer exception even if you have your reference variable pointing to null because static variables and method calls are bonded during compile time based on the class name and not associated with the object.

Please let me know if you know some more such language constructs which do not fail when null is encountered.

5. What if we must allow NullPointerException in Some Places

Joshua bloch in effective java says that “Arguably, all erroneous method invocations boil down to an illegal argument or illegal state, but other exceptions are standardly used for certain kinds of illegal arguments and states. If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException be thrown rather than IllegalArgumentException .”

So if you must allow NullPointerException in some places in your code then make sure you make them more informative than they usually are.

Take a look at the below example:

Output of both method calls is this:

Clearly, the second stack trace is more informative and makes debugging easy. Use this in the future.

I am done with my experience around NullPointerException. If you know other points around the topic, please share with all of us !!

Источник

Оцените статью
toolgir.ru
Adblock
detector