В этом посте я представлю вам одну из самых распространенных ошибок в мире программирования. Что такое исключение NullPointerException в Java? Я попытаюсь объяснить тему, представлю много примеров использования и постараюсь использовать диаграммы, которые легко (надеюсь) показывают, что происходит под капотом в Java-коде. и почему вы получаете Ошибка NullPointerException!
Оглавление
- Что такое исключение NullPointerException в Java?
- Подробное описание исключения NullPointerException (Java Null)
- Исправленный код
- Пояснение к диаграмме
- Пример пользовательского класса
- Сделать сложнее
- Сводка
Что такое исключение 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. И еще лучшее решение — предвидеть, что может пойти не так в коде, и соответствующим образом перенаправить его, то есть использовать концепцию Или концепция. Но об этом я напишу в другой статье. Мы также рекомендуем вам следить за новостями или использовать поисковую лупу в правом верхнем углу блога.
Лучший способ найти нулевое место в коде — запустить программу в режиме отладки. Тогда мы сможем проследить код и увидеть на выбранных этапах выполнения программы, какое значение имеет каждый объект. Мы можем поймать ошибку в акте!
Проверьте мой блог!
Проверьте другие сообщения в моем блоге!