Введение
В этом практическом занятии (лабораторной работе) вы научитесь безопасно работать с объектами-обёртками Integer в Java, с особым вниманием уделяя проверке на null. В отличие от примитивного типа int, Integer представляет собой объект, который может иметь null-ссылку, и если не проверить на null, это может привести к распространённым ошибкам NullPointerException.
С помощью практических примеров вы рассмотрите базовую проверку на == null, сочетание проверки на null с сравнением значений и, наконец, узнаете, как использовать класс Optional для более надежного и выразительного обработки null в вашем Java-коде.
Проверка объекта-обертки Integer на null
На этом этапе мы рассмотрим, как работать с объектами-обёртками Integer в Java, с особым вниманием уделяя проверке на null. В отличие от примитивных типов, таких как int, Integer представляет собой класс, что означает, что переменная типа Integer может хранить ссылку на объект или быть равной null, если она не ссылается на какой-либо объект. Обработка значений null является важной частью программирования на Java, чтобы избежать ошибок NullPointerException, которые очень распространены и могут привести к аварийному завершению программы.
Создадим простую Java-программу, которая демонстрирует проверку на null для объекта Integer.
Откройте файл
HelloJava.javaв редакторе WebIDE. Если вы завершили предыдущую лабораторную работу (практическое занятие), этот файл должен уже существовать в директории~/project.Замените существующий код в файле
HelloJava.javaследующим:public class HelloJava { public static void main(String[] args) { Integer myInteger = null; // Declaring an Integer and setting it to null // Check if myInteger is null if (myInteger == null) { System.out.println("myInteger is null."); } else { System.out.println("myInteger is not null. Its value is: " + myInteger); } // Let's try with a non-null Integer Integer anotherInteger = 10; // Declaring and initializing with a value // Check if anotherInteger is null if (anotherInteger == null) { System.out.println("anotherInteger is null."); } else { System.out.println("anotherInteger is not null. Its value is: " + anotherInteger); } } }В этом коде:
- Мы объявляем переменную
myIntegerтипаIntegerи явно устанавливаем ее значение равнымnull. - Используем оператор
==в условном оператореifдля проверки, является лиmyIntegerравнымnull. Это стандартный способ проверки наnullссылки на объект в Java. - Затем объявляем другую переменную
anotherIntegerтипаIntegerи присваиваем ей значение10. Java автоматически преобразует примитивное значениеint10в объектInteger(это называется автоупаковкой, autoboxing). - Выполняем ту же проверку на
nullдляanotherInteger.
- Мы объявляем переменную
Сохраните файл
HelloJava.java(Ctrl+S или Cmd+S).Теперь скомпилируйте программу с помощью команды
javacв терминале. Убедитесь, что вы находитесь в директории~/project.javac HelloJava.javaЕсли ошибок нет, компиляция пройдет без сообщений, и в директории
~/projectбудет создан файлHelloJava.class.Запустите скомпилированную программу с помощью команды
java:java HelloJavaВы должны увидеть вывод, похожий на следующий:
myInteger is null. anotherInteger is not null. Its value is: 10Этот вывод подтверждает, что наша проверка на
nullработает корректно как дляIntegerс значениемnull, так и для не-nullобъектаInteger. Понимание того, как проверять наnull, является фундаментальным навыком в программировании на Java, особенно при работе с классами-обёртками и объектами, которым не всегда присваивается значение.
Сочетание проверок на null и значения
На предыдущем этапе мы научились проверять, является ли объект Integer равным null. Часто вам нужно будет проверить, не является ли Integer равным null И удовлетворяет ли его значение определенному условию. Совмещение этих проверок важно, так как попытка получить значение Integer, равного null, приведет к ошибке NullPointerException.
Давайте модифицируем нашу программу, чтобы продемонстрировать сочетание проверки на null с проверкой значения.
Откройте файл
HelloJava.javaв редакторе WebIDE.Замените существующий код следующим:
public class HelloJava { public static void main(String[] args) { Integer score = null; // Example 1: score is null // Check if score is not null AND its value is greater than 50 if (score != null && score > 50) { System.out.println("Score is not null and is greater than 50."); } else { System.out.println("Score is null or not greater than 50."); } Integer anotherScore = 75; // Example 2: score is 75 // Check if anotherScore is not null AND its value is greater than 50 if (anotherScore != null && anotherScore > 50) { System.out.println("anotherScore is not null and is greater than 50."); } else { System.out.println("anotherScore is null or not greater than 50."); } Integer yetAnotherScore = 40; // Example 3: score is 40 // Check if yetAnotherScore is not null AND its value is greater than 50 if (yetAnotherScore != null && yetAnotherScore > 50) { System.out.println("yetAnotherScore is not null and is greater than 50."); } else { System.out.println("yetAnotherScore is null or not greater than 50."); } } }В этом обновленном коде:
- Мы используем логический оператор И (
&&), чтобы объединить два условия:score != nullиscore > 50. - Проверка
score != nullставится первой. В Java оператор&&использует сокращенную оценку (short - circuit evaluation). Это означает, что если первое условие (score != null) ложно, второе условие (score > 50) не оценивается. Это предотвращает ошибкуNullPointerException, когдаscoreравенnull, так как кодscore > 50не будет выполнен. - Мы тестируем эту логику на трех разных переменных типа
Integer: одной, которая равнаnull, одной, которая не равнаnullи больше 50, и одной, которая не равнаnull, но не больше 50.
- Мы используем логический оператор И (
Сохраните файл
HelloJava.java.Скомпилируйте модифицированную программу в терминале:
javac HelloJava.javaЗапустите скомпилированную программу:
java HelloJavaВы должны увидеть вывод, похожий на следующий:
Score is null or not greater than 50. anotherScore is not null and is greater than 50. yetAnotherScore is null or not greater than 50.Этот вывод демонстрирует, как работает совмещенная проверка. В первом случае правильно определяется, что
scoreравенnull. Во втором случае определяется, чтоanotherScoreне равенnullи больше 50. В третьем случае определяется, чтоyetAnotherScoreне больше 50, даже если он не равенnull. Этот шаблон проверки наnullперед доступом к свойствам или значению объекта является фундаментальной практикой безопасности в Java.
Использование Optional для безопасной обработки
Хотя проверка на null с помощью == null и комбинирование проверок с помощью && является эффективной, в Java 8 был введен класс Optional как более идиоматический способ обработки значений, которые могут отсутствовать (то есть быть null). Optional представляет собой контейнерный объект, который может содержать или не содержать не-null значение. Использование Optional может сделать ваш код более читаемым и менее подверженным ошибкам NullPointerException.
На этом этапе мы рефакторим нашу программу, чтобы использовать Optional<Integer> для обработки потенциально отсутствующих целочисленных значений.
Откройте файл
HelloJava.javaв редакторе WebIDE.Замените существующий код следующим:
import java.util.Optional; public class HelloJava { public static void main(String[] args) { // Example 1: Optional containing a null value (empty Optional) Optional<Integer> optionalScoreNull = Optional.empty(); // Check if the Optional contains a value and if it's greater than 50 if (optionalScoreNull.isPresent() && optionalScoreNull.get() > 50) { System.out.println("optionalScoreNull is present and greater than 50."); } else { System.out.println("optionalScoreNull is empty or not greater than 50."); } // Example 2: Optional containing a non-null value (75) Optional<Integer> optionalScorePresent = Optional.of(75); // Check if the Optional contains a value and if it's greater than 50 if (optionalScorePresent.isPresent() && optionalScorePresent.get() > 50) { System.out.println("optionalScorePresent is present and greater than 50."); } else { System.out.println("optionalScorePresent is empty or not greater than 50."); } // Example 3: Optional containing a non-null value (40) Optional<Integer> optionalScoreNotGreater = Optional.of(40); // Check if the Optional contains a value and if it's greater than 50 if (optionalScoreNotGreater.isPresent() && optionalScoreNotGreater.get() > 50) { System.out.println("optionalScoreNotGreater is present and greater than 50."); } else { System.out.println("optionalScoreNotGreater is empty or not greater than 50."); } // A more functional way using Optional methods System.out.println("\nUsing Optional methods:"); optionalScoreNull.ifPresent(value -> System.out.println("Value from optionalScoreNull: " + value)); optionalScorePresent.ifPresent(value -> System.out.println("Value from optionalScorePresent: " + value)); optionalScoreNotGreater.ifPresent(value -> System.out.println("Value from optionalScoreNotGreater: " + value)); // Using orElse to provide a default value if Optional is empty Integer scoreOrDefault = optionalScoreNull.orElse(0); System.out.println("Value from optionalScoreNull with default: " + scoreOrDefault); // Using filter for conditional checks optionalScorePresent.filter(value -> value > 50) .ifPresent(value -> System.out.println("Filtered optionalScorePresent value: " + value)); optionalScoreNotGreater.filter(value -> value > 50) .ifPresent(value -> System.out.println("Filtered optionalScoreNotGreater value: " + value)); } }Рассмотрим ключевые изменения:
import java.util.Optional;: Мы импортируем классOptional.Optional<Integer> optionalScoreNull = Optional.empty();: Мы создаем пустойOptionalдля представления отсутствия значения.Optional<Integer> optionalScorePresent = Optional.of(75);: Мы создаемOptional, содержащий не-nullзначение, используяOptional.of(). Обратите внимание, чтоOptional.of()выброситNullPointerException, если передать емуnullзначение. Если значение может бытьnull, используйтеOptional.ofNullable().optionalScoreNull.isPresent(): Этот метод проверяет, содержит лиOptionalзначение. Это рекомендуемый способ проверки наличия значения вместо проверки наnull.optionalScoreNull.get(): Этот метод извлекает значение изOptional. Будьте осторожны! ЕслиOptionalпуст, вызовget()выброситNoSuchElementException. Вот почему вы всегда должны проверятьisPresent()перед вызовомget()или использовать другие методыOptional, которые элегантно обрабатывают случай пустогоOptional.optionalScoreNull.ifPresent(value -> ...): Этот метод выполняет предоставленный код только в том случае, еслиOptionalсодержит значение. Это чистый способ выполнить действие над значением, если оно существует.optionalScoreNull.orElse(0): Этот метод возвращает значение, если оно присутствует, в противном случае возвращает указанное значение по умолчанию (в данном случае 0).optionalScorePresent.filter(value -> value > 50): Этот метод возвращаетOptional, содержащий значение, если оно присутствует И соответствует заданному условию (значение > 50), в противном случае возвращает пустойOptional.
Сохраните файл
HelloJava.java.Скомпилируйте программу в терминале:
javac HelloJava.javaЗапустите скомпилированную программу:
java HelloJavaВы должны увидеть вывод, похожий на следующий:
optionalScoreNull is empty or not greater than 50. optionalScorePresent is present and greater than 50. optionalScoreNotGreater is empty or not greater than 50. Using Optional methods: Value from optionalScorePresent: 75 Value from optionalScoreNotGreater: 40 Value from optionalScoreNull with default: 0 Filtered optionalScorePresent value: 75Этот вывод показывает, как можно использовать
Optionalдля обработки наличия или отсутствия значений и безопасного выполнения операций. Хотя шаблонif (isPresent() && get() > 50)похож на проверку наnull,Optionalпредоставляет много других полезных методов (ifPresent,orElse,filter,mapи т.д.), которые могут привести к более выразительному и безопасному коду при работе с потенциально отсутствующими значениями. ИспользованиеOptionalявляется хорошей практикой в современной разработке на Java.
Резюме
В этом практическом занятии (лабораторной работе) мы научились проверять, является ли объект-обертка Integer в Java равным null. Мы начали с понимания того, что Integer - это класс, и он может содержать ссылку на null, в отличие от примитивного типа int. Мы продемонстрировали базовую проверку == null с помощью простой Java-программы, показав, как обрабатывать как null, так и не-null переменные типа Integer, чтобы предотвратить ошибку NullPointerException.



