Решение java.lang.NullPointerException в Java: причины и способы

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вы столкнулись с NullPointerException (NPE), выполните проверку на null перед обращением к методам или полям объекта:

Java
Скопировать код
if (obj != null) obj.method();

Инициализируйте объекты при их объявлении:

Java
Скопировать код
Object obj = new Object();

Для обработки null-ссылок можно использовать Java 8 Optional:

Java
Скопировать код
Optional.ofNullable(obj).ifPresent(Object::method);

Тщательно проанализируйте стек вызовов для определения места возникновения NPE.

Основные стратегии предотвращения NullPointerException

Инициализация объектов

Неинициализированный объект — распространённая причина ошибки null. Всегда производите инициализацию:

Java
Скопировать код
TypeA objA; // Так делать нельзя, objA равно null.
TypeA objA = new TypeA(); // Правильный подход, objA не равно null.

Условные проверки и утверждения

Условные проверки защищают от NPE:

Java
Скопировать код
if (obj != null) {
    obj.method();
}

Утверждения добавляют дополнительную безопасность:

Java
Скопировать код
assert obj != null : "obj обязательно должен существовать!";

Использование Java 8 и новых возможностей языка

Используйте новшества Java для элегантной работы с null:

Java
Скопировать код
Optional.ofNullable(obj).ifPresent(o -> o.method());

С Java 14 становится возможным получить больше сведений о null-ссылках:

log
Скопировать код
// До Java 14: NullPointerException
// Начиная с Java 14: NullPointerException: Не вызывайте 'obj.method()', 'obj' равно null!

Ошибка в коде может быть обнаружена статическими анализаторами кода:

Markdown
Скопировать код
Правило SonarQube: S2259 – Нельзя разыменовывать null указатели

Особый акцент на массивы

Не забудьте, что массивы инициализируются null:

Java
Скопировать код
String[] strings = new String[10]; // все элементы от strings[0] до strings[9] изначально равны null!

Тонкости обработки null

API, исключающие null

Воспользуйтесь API, которые не допускают появление null значений:

Java
Скопировать код
Objects.requireNonNull(obj, "obj не должен быть null!"); // Вызывает NPE, если obj равен null.

Значения по умолчанию и операции, безопасные при использовании null

Предусмотрите значения по умолчанию, чтобы не столкнуться с null:

Java
Скопировать код
String string = (nullableString != null) ? nullableString : "Дефолтное значение";

Операции, безопасные в отношении null, удобны при сравнении строк:

Java
Скопировать код
boolean isEqual = "defaultString".equals(nullableString); // null-безопасное сравнение

Разбиение кода на модули

Лаконичный код — залог успешной разработки:

Java
Скопировать код
public ReturnType modularMethod(Params p) {
    Step1 step1 = stepOne(p);
    if (step1 == null) throw new CustomException("Ошибка на шаге 1");
  
    Step2 step2 = stepTwo(step1);
    if (step2 == null) throw new CustomException("Ошибка на шаге 2");

    return finalStep(step2);
}

Специфика для Android

Разработчикам на Android: убеждайтесь, что элементы интерфейса, найденные при помощи findViewById, не равны null:

Java
Скопировать код
TextView textView = findViewById(R.id.textView);
if (textView != null) {
    textView.setText("Привет, Android!");
}

Визуализация

Воспринимайте NullPointerException как попытку переключить выключатель света в несуществующей комнате:

Markdown
Скопировать код
🏗️🧱🔲 : [Основание, Стены, ❓]

Попытка взаимодействия:

Java
Скопировать код
Room room = null;
System.out.println(room.lightSwitch);

NullPointerException: 💥 Нет комнаты. Нет выключателя.

Решение: Сначала постройте комнату, затем ищите выключатель.

Markdown
Скопировать код
🏗️🧱🔲➡️🏠🔲 : [Основание, Стены, Выключатель света]
Java
Скопировать код
Room room = new Room();
System.out.println(room.lightSwitch);

Основная идея: Объекты должны быть созданы (🏠) до их использования.

Отладка и понимание NullPointerException

Подробная информация о проблеме

При поиске помощи предоставляйте максимально подробную информацию об ошибке и стеке вызовов:

Java
Скопировать код
try {
    // Потенциальное место возникновения NPE
} catch (NullPointerException e) {
    e.printStackTrace();
}

Основы понимания

Изучите правила работы с null из Спецификации языка Java:

Markdown
Скопировать код
JLS §4.1 – Виды типов и значения: ссылочные типы и значения

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

Полезные материалы

  1. NullPointerException (Java Platform SE 7) — Официальная документация NullPointerException.
  2. java – What is a NullPointerException, and how do I fix it? – Stack Overflow — Обсуждение NullPointerException на Stack Overflow.
  3. Учебник | DigitalOcean — Руководство по NullPointerException от DigitalOcean.
  4. Java – Исключения — Tutorialspoint по обработке исключений в Java, включая NullPointerException.
  5. Просто мгновение... — Обширная статья от Baeldung о диагностировании и исправлении NullPointerException.