Java lang nullpointerexception api

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

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

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

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

Integer n1 = null; System.out.println(n1.toString());

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

Exception in thread "main" java.lang.NullPointerException at ru.javalessons.errors.NPEExample.main(NPEExample.java:6)

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

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

Integer n1 = 16; System.out.println(n1.toString());

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

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

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

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

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

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

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

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

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

Читайте также:  Python calling windows command

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

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

Заключение

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

Источник

Как понять NullPointerException

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

  1. Его кинули с помощью throw
  2. Кто-то кинул null с помощью throw
  3. Кто-то пытается обратиться по null-ссылке
  1. Вызов нестатического метода класса
  2. Обращение (чтение или запись) к нестатическому полю
  3. Обращение (чтение или запись) к элементу массива
  4. Чтение length у массива
  5. Неявный вызов метода valueOf при анбоксинге (unboxing)
 1: class Data < 2: private String val; 3: public Data(String val) 4: public String getValue() 5: > 6: 7: class Formatter < 8: public static String format(String value) < 9: return value.trim(); 10: >11: > 12: 13: public class TestNPE < 14: public static String handle(Formatter f, Data d) < 15: return f.format(d.getValue()); 16: >17: >
Exception in thread "main" java.lang.NullPointerException at TestNPE.handle(TestNPE.java:15)

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

 1: class Formatter < 2: public String format(String value) < 3: return "["+value+"]"; 4: >5: > 6: 7: public class TestNPE < 8: public static String handle(Formatter f, String s) < 9: if(s.isEmpty()) < 10: return "(none)"; 11: >12: return f.format(s.trim()); 13: > 14: >
Exception in thread "main" java.lang.NullPointerException at TestNPE.handle(TestNPE.java:12)

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

Читайте также:  Произведение чисел от 1 до 100 питон

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

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

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

 1: import java.io.PrintWriter; 2: 3: public class TestNPE < 4: public static void dump(PrintWriter pw, MyObject obj) < 5: pw.print(obj); 6: >7: >
Exception in thread "main" java.lang.NullPointerException at java.io.PrintWriter.write(PrintWriter.java:473) at java.io.PrintWriter.print(PrintWriter.java:617) at TestNPE.dump(TestNPE.java:5)

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

472: public void write(String s)

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

616: public void print(Object obj)

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

public static String valueOf(Object obj)

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

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

Exception in thread "main" java.lang.NullPointerException at TestNPE.getCount(TestNPE.java:3)

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

import java.util.List; public class MyContainer < Listelements; public MyContainer(List elements) < this.elements = elements; >public Integer getCount() < return elements == null ? null : elements.size(); >>

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

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

Читайте также:  Valueerror source code string cannot contain null bytes python

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

Источник

Null Pointer Exception Class

Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.

Thrown when an application attempts to use null in a case where an object is required.

[Android.Runtime.Register("java/lang/NullPointerException", DoNotGenerateAcw=true)] public class NullPointerException : Java.Lang.RuntimeException
[] type NullPointerException = class inherit RuntimeException

Remarks

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

Constructors

Constructs a NullPointerException with no detail message.

A constructor used when creating managed representations of JNI objects; called by the runtime.

Constructs a NullPointerException with the specified detail message.

Fields

Properties

Returns the cause of this throwable or null if the cause is nonexistent or unknown.

The handle to the underlying Android instance.

Creates a localized description of this throwable.

Returns the detail message string of this throwable.

This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.

This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.

Methods

Appends the specified exception to the exceptions that were suppressed in order to deliver this exception.

Fills in the execution stack trace.

Provides programmatic access to the stack trace information printed by #printStackTrace() .

Returns an array containing all of the exceptions that were suppressed, typically by the try -with-resources statement, in order to deliver this exception.

Initializes the cause of this throwable to the specified value.

Prints this throwable and its backtrace to the standard error stream.

Prints this throwable and its backtrace to the specified print stream.

Prints this throwable and its backtrace to the specified print writer.

Sets the stack trace elements that will be returned by #getStackTrace() and printed by #printStackTrace() and related methods.

Explicit Interface Implementations

IJavaPeerable.Disposed() (Inherited from Throwable)
IJavaPeerable.DisposeUnlessReferenced() (Inherited from Throwable)
IJavaPeerable.Finalized() (Inherited from Throwable)
IJavaPeerable.JniManagedPeerState (Inherited from Throwable)
IJavaPeerable.SetJniIdentityHashCode(Int32) (Inherited from Throwable)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) (Inherited from Throwable)
IJavaPeerable.SetPeerReference(JniObjectReference) (Inherited from Throwable)

Extension Methods

Performs an Android runtime-checked type conversion.

Источник

Оцените статью