Что такое Null Pointer Exception и как его исправить?

439
22 января 2017, 14:20

Что из себя представляет исключение Null Pointer Exception (java.lang.NullPointerException) и почему оно может происходить?

Какие методы и средства использовать, чтобы определить причину возникновения этого исключения, приводящего к преждевременному прекращению работы приложения?

Перевод вопроса «What is a Null Pointer Exception, and how do I fix it?» @Ziggy.

Answer 1

Когда вы объявляете переменную ссылочного типа, на самом деле вы создаете ссылку на объект данного типа. Рассмотрим следующий код для объявления переменной типа int:

int x;
x = 10;

В этом примере переменная x имеет тип int и Java инициализирует её как 0. Когда вы присвоите переменной значение 10 (вторая строка), это значение сохранится в ячейке памяти, на которую ссылается x.

Но когда вы объявляете ссылочный тип, процесс выглядит иначе. Посмотрим на следующий код:

Integer num;
num = new Integer(10);

В первой строке объявлена переменная num, ее тип не относится к встроенному, следовательно, значением является ссылка (тип этой переменной, Integer, является ссылочным типом). Поскольку вы еще не указали, на что собираетесь ссылаться, Java присвоит переменной значение Null, подразумевая «Я ни на что не ссылаюсь».

Во второй строке, ключевое слово new используется для создания объекта типа Integer. Этот объект имеет адрес в памяти, который присваивается переменной num. Теперь, с помощью переменной num вы можете обратиться к объекту используя оператора разыменования ..

Исключение, о котором вы говорите в вопросе, возникает, если вы объявили переменную, но не создали объект, то есть если вы попытаетесь разыменовать num до того, как создали объект, вы получите NullPointerException. В самом простом случае, компилятор обнаружит проблему и сообщит, что

num may not have been initialized

Что говорит: «возможно, переменная num не инициализирована».

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

public void doSomething(Integer num){
   // Работаем с num
}

В этом случае создание объекта (переменная num) лежит на вызывающем коде, то есть вы предполагаете, что он был создан ранее – до вызова метода doSomething. К сожалению, следующий вызов метода вполне возможен:

doSomething(null);

В этом случае значение переменной num будет null. Лучшим способом избежать данного исключения будет проверка на равенство нулю. Как результат, функция doSomething должна быть переписана следующим образом:

public void doSomething(Integer num){
    if (num != null) {
       // Работаем с num
    }
}

Как альтернативный вариант предыдущему примеру вы можете сообщить вызывающему коду, что метод был вызван с неверными параметрами, например, с помощью IllegalArgumentException.

public void doSomething(Integer num){
    if (num == null)
        throw new IllegalArgumentException("Num не должен быть null"); 
    // Работаем с num
}

Также, обратите внимание на вопрос «Что такое stack trace и как с его помощью находить ошибки при разработке приложений?».

Перевод ответа «What is a Null Pointer Exception, and how do I fix it?» @Vincent Ramdhanie.

READ ALSO
jquery and html select

jquery and html select

Доброго времени суток всем, столкнулся с такой проблемой есть одно поле ввода input id="siF3" и виподаюши список select id="country" в списке несколько стран...

368
Помощь с Semantic UI

Помощь с Semantic UI

Доброго времени суток, подскажите пожалуйста почему может не работать выпадающий список Compact Dropdown если сделать append всего блока

372
Отступы от иконок

Отступы от иконок

Добавил напротив иконок ссылки,добавил отступы иконкам в ,но ссылки идут не ровно в столбецПолагаю из за разного размера иконок

328
Вопросы по верстке

Вопросы по верстке

<nav> <a href="#"></a> <a href="#"></a> <a href="#"></a> <a href="#"></a> </nav>

310