В этом посте я представлю вам одну из самых распространенных ошибок в мире программирования. Что такое исключение NullPointerException в Java? Я попытаюсь объяснить тему, представлю много примеров использования и постараюсь использовать диаграммы, которые легко (надеюсь) показывают, что происходит под капотом в Java-коде. и почему вы получаете Ошибка NullPointerException!

Оглавление

Что такое исключение NullPointerException в Java?

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

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

NullPointerException в деталях (Java Null)

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

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

public class BigDataETLNullPointerException {

    public static void main(String[] args) {
        String myString = null; // Variable is the reference to memory
        System.out.println(myString.length());
    }
}

Вывод ошибки:

Exception in thread "main" java.lang.NullPointerException
    at BigDataETLNullPointerException.main(BigDataETLNullPointerException.java:5)

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

Исправленный код

А теперь мы исправим наш приведенный выше код, чтобы он инициализировал значение переменной myString. Благодаря этому в памяти компьютера будет создан объект класса String, на который у нас будут ссылки в виде переменной myString.

public class BigDataETLNullPointerException {

    public static void main(String[] args) {
        String myString = "BigData-ETL";
        System.out.println("The length of myString variable is : " + myString.length());
    }
}

Выход:

The length of myString variable is : 11

Пояснение к диаграмме

Как и в предыдущей части, давайте привыкнем к диаграмме, каково состояние памяти компьютера. Мы видим, что ссылка (черная стрелка) теперь указывает на объект в памяти компьютера, который существует, потому что мы создали его посредством инициализации — присвоения ему значения. Таким образом, когда мы затем выполним метод length для нашей переменной, код будет успешным.

Пример пользовательского класса

Теперь давайте рассмотрим пример с любым классом. Для этого примера я создал класс Point с двумя переменными: x, y и методом @Override toString:

public class Point {
    private Integer x;
    private Integer y;

    public Point(Integer x, Integer y) {
        this.x = x;
        this.y = y;
    }

    public Integer getX() {
        return x;
    }

    public Integer getY() {
        return y;
    }

    @Override
    public String toString() {
        return "Point{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

Далее мы попытаемся инициализировать объект Point объект и вызвать метод toString. В этом случае IDEA даже не даст вам выполнить код, потому что уже на уровне компиляции вы получите ошибку:

java: variable pointB might not have been initialized

Вызов:

public class BigDataETLNullPointerException {

    public static void main(String[] args) {
        Point pointA = new Point(10, 10);
        System.out.println(pointA);

        Point pointB;
        System.out.println(pointB);

    }
}

Сделай это сложнее

Теперь сделаем так, чтобы на уровне компиляции все было ок и они не получили ни одной ошибки. Давайте создадим вспомогательный метод createNewPointBasedOn. Этот метод принимает Point в качестве параметра и на его основе возвращает новую точку, где мы добавляем +5 к каждой из его переменных.

private static Point createNewPointBasedOn(Point point) {
        return new Point(point.getX() + 5, point.getY() + 5);
    }

Теперь давайте попробуем этот метод:

public class BigDataETLNullPointerException {

    public static void main(String[] args) {
        Point pointA = new Point(null, 10);
        Point pointB = createNewPointBasedOn(pointA);
        System.out.println(pointB);
    }

    private static Point createNewPointBasedOn(Point point) {
        return new Point(point.getX() + 5, point.getY() + 5);
    }
}

Вывод — Исключение:

Exception in thread "main" java.lang.NullPointerException
    at BigDataETLNullPointerException.createNewPointBasedOn(BigDataETLNullPointerException.java:10)
    at BigDataETLNullPointerException.main(BigDataETLNullPointerException.java:5)

Краткое содержание

Надеюсь, теперь, если вы получите ошибку NullPointerException в Java, вы будете знать, что ее вызывает.
Самое сложное в этом случае — выяснить, почему мы получаем null где-то в коде.

Лучший способ избежать ошибок такого типа — использовать правильную обработку ошибок и избегать нулевых значений. Подумайте, как написать лучшие методы/функции, чтобы никогда не получить значение null.

Хорошей практикой является перенос значений, суммированных как объекты Option. И еще лучшее решение — предвидеть, что может пойти не так в коде, и соответствующим образом перенаправить его, то есть использовать концепцию Или концепция. Но об этом я напишу в другой статье. Мы также рекомендуем вам следить за новостями или использовать поисковую лупу в правом верхнем углу блога.

Лучший способ найти нулевое место в коде — запустить программу в режиме отладки. Тогда мы сможем проследить код и увидеть на выбранных этапах выполнения программы, какое значение имеет каждый объект. Мы можем поймать ошибку в акте!

Проверьте мой блог!

Проверьте другие сообщения в моем блоге!