Введение
В этом лабораторном занятии вы научитесь безопасно обрабатывать значения null при работе с объектами Boolean в Java. Мы рассмотрим потенциальные ловушки, связанные с NullPointerException, при работе с оберткой Boolean по сравнению с примитивным типом boolean.
Вы узнаете правильный способ проверки, является ли объект Boolean равным null перед доступом к его значению, научитесь использовать класс Optional для более надежного обработки null-значений и поймете ключевые различия в поведении null между примитивным типом boolean и оберткой Boolean на практических примерах.
Проверка объекта Boolean на null
На этом этапе мы рассмотрим, как обрабатывать потенциальные значения null при работе с объектами Boolean в Java. В отличие от примитивных типов boolean, которые всегда равны либо true, либо false, обертка Boolean может иметь значение null. Это является распространенной причиной ошибок NullPointerException, если не обрабатывать это осторожно.
Создадим простую Java-программу, чтобы продемонстрировать это.
Откройте редактор WebIDE.
В проводнике файлов слева убедитесь, что вы находитесь в директории
~/project.Щелкните правой кнопкой мыши в пустом пространстве проводника файлов, выберите "Новый файл" и назовите его
BooleanCheck.java.Откройте файл
BooleanCheck.javaв редакторе.Скопируйте и вставьте следующий код в редактор:
public class BooleanCheck { public static void main(String[] args) { Boolean myBoolean = null; // This will cause a NullPointerException if myBoolean is null // if (myBoolean) { // System.out.println("myBoolean is true"); // } // Correct way to check for null before accessing the boolean value if (myBoolean != null && myBoolean) { System.out.println("myBoolean is true"); } else if (myBoolean == null) { System.out.println("myBoolean is null"); } else { System.out.println("myBoolean is false"); } } }В этом коде:
- Мы объявляем объект
Booleanс именемmyBooleanи инициализируем его значениемnull. - Закомментированная строка
if (myBoolean)показывает распространенную ошибку, которая приводит кNullPointerException, когдаmyBooleanравноnull. - Строка
if (myBoolean != null && myBoolean)демонстрирует правильный способ проверки, не является ли объектBooleanравнымnullперед попыткой оценить его булево значение. Оператор&&является оператором с коротким замыканием, то есть еслиmyBoolean != nullравноfalse, вторая часть (myBoolean) не оценивается, что предотвращает ошибку.
- Мы объявляем объект
Сохраните файл (Ctrl+S или Cmd+S).
Откройте терминал внизу WebIDE. Убедитесь, что вы находитесь в директории
~/projectс помощью командыcd ~/project.Скомпилируйте Java-программу, введя следующую команду и нажав Enter:
javac BooleanCheck.javaЕсли нет ошибок, вы не увидите никакого вывода. Файл
BooleanCheck.classбудет создан в директории~/project.Запустите скомпилированную программу с помощью следующей команды и нажмите Enter:
java BooleanCheckВы должны увидеть следующий вывод:
myBoolean is null
Этот вывод подтверждает, что наша программа правильно определила, что myBoolean было равно null и избежала NullPointerException. Понимание того, как обрабатывать null с объектами Boolean, является важной частью написания надежного Java-кода.
Использование Optional для обработки null
На этом этапе мы рассмотрим более современный подход к обработке потенциальных значений null в Java с использованием класса Optional, введенного в Java 8. Optional представляет собой контейнерный объект, который может содержать или не содержать не-null значение. Он предоставляет ясный способ указать, что значение может отсутствовать, помогая предотвратить ошибки NullPointerException и делая код более читаемым.
Давайте модифицируем наш предыдущий пример, чтобы использовать Optional<Boolean>.
Откройте файл
BooleanCheck.javaв редакторе WebIDE.Замените все содержимое файла следующим новым кодом:
import java.util.Optional; public class BooleanCheck { public static void main(String[] args) { // Creating an Optional that contains a Boolean value Optional<Boolean> optionalBooleanPresent = Optional.of(true); // Creating an Optional that is empty (represents null) Optional<Boolean> optionalBooleanEmpty = Optional.empty(); // Handling the present Optional if (optionalBooleanPresent.isPresent()) { System.out.println("optionalBooleanPresent has a value: " + optionalBooleanPresent.get()); } else { System.out.println("optionalBooleanPresent is empty"); } // Handling the empty Optional if (optionalBooleanEmpty.isPresent()) { System.out.println("optionalBooleanEmpty has a value: " + optionalBooleanEmpty.get()); } else { System.out.println("optionalBooleanEmpty is empty"); } // Using orElse to provide a default value if the Optional is empty Boolean valueOrDefault = optionalBooleanEmpty.orElse(false); System.out.println("Value from optionalBooleanEmpty orElse(false): " + valueOrDefault); // Using ifPresent to perform an action only if a value is present optionalBooleanPresent.ifPresent(value -> System.out.println("Value is present: " + value)); } }В этом обновленном коде:
- Мы импортируем класс
java.util.Optional. - Мы создаем два объекта
Optional<Boolean>: один с значением (Optional.of(true)) и один пустой (Optional.empty()). - Мы используем метод
isPresent(), чтобы проверить, содержит лиOptionalзначение. - Мы используем метод
get(), чтобы извлечь значение изOptional. Примечание: Вызовget()для пустогоOptionalвызовет исключениеNoSuchElementException, поэтому всегда проверяйте с помощьюisPresent()сначала или используйте другие методыOptional. - Мы демонстрируем метод
orElse(false), который возвращает содержащееся значение, если оно есть, в противном случае возвращает указанное значение по умолчанию (в данном случаеfalse). - Мы показываем метод
ifPresent(), который принимает лямбда-выражение и выполняет его только в том случае, если вOptionalесть значение.
- Мы импортируем класс
Сохраните файл (Ctrl+S или Cmd+S).
Откройте терминал внизу WebIDE. Убедитесь, что вы находитесь в директории
~/projectс помощью командыcd ~/project.Скомпилируйте Java-программу, введя следующую команду и нажав Enter:
javac BooleanCheck.javaЕсли компиляция прошла успешно, будет сгенерирован новый файл
BooleanCheck.class.Запустите скомпилированную программу с помощью следующей команды и нажмите Enter:
java BooleanCheckВы должны увидеть следующий вывод:
optionalBooleanPresent has a value: true optionalBooleanEmpty is empty Value from optionalBooleanEmpty orElse(false): false Value is present: true
Этот вывод показывает, как можно использовать Optional для более явной и безопасной обработки наличия или отсутствия значения, чем просто использование null. Использование Optional может сделать ваш код более понятным и уменьшить вероятность возникновения NullPointerException.
Тестирование примитивных типов и оберток
На этом этапе мы подчеркнем ключевое различие между примитивным типом boolean в Java и оберткой Boolean, в частности, в их способности принимать значение null. Понимание этого различия является фундаментальным для избежания ошибок NullPointerException при работе с булевыми значениями.
- Примитивный тип
boolean: Это основной тип данных в Java. Он может хранить только одно из двух значений:trueилиfalse. Переменная примитивного типаbooleanникогда не может быть равнаnull. - Обертка
Boolean: Это объект, который оборачивает примитивное значениеboolean. Поскольку это объект, переменная типаBooleanможет ссылаться на объектBoolean(который содержитtrueилиfalse), или она может иметь значениеnull.
Создадим простую программу, чтобы продемонстрировать это различие.
Откройте редактор WebIDE.
В проводнике файлов слева убедитесь, что вы находитесь в директории
~/project.Щелкните правой кнопкой мыши в пустом пространстве проводника файлов, выберите "Новый файл" и назовите его
PrimitiveVsWrapper.java.Откройте файл
PrimitiveVsWrapper.javaв редакторе.Скопируйте и вставьте следующий код в редактор:
public class PrimitiveVsWrapper { public static void main(String[] args) { // Declaring a primitive boolean boolean primitiveBoolean = true; // Declaring a Boolean wrapper object Boolean wrapperBoolean = null; // Wrapper can be null System.out.println("Primitive boolean value: " + primitiveBoolean); // Checking if the wrapper Boolean is null before printing if (wrapperBoolean == null) { System.out.println("Wrapper Boolean is null"); } else { System.out.println("Wrapper Boolean value: " + wrapperBoolean); } // Attempting to assign null to a primitive boolean will cause a compile-time error // primitiveBoolean = null; // Uncommenting this line will cause an error } }В этом коде:
- Мы объявляем примитивный тип
booleanи инициализируем его значениемtrue. - Мы объявляем объект обертки
Booleanи инициализируем его значениемnull. Это допустимо для обертки. - Мы выводим значение примитивного типа
boolean. - Мы проверяем, является ли обертка
Booleanравнойnullперед попыткой вывести ее значение, демонстрируя необходимость проверок наnullдля типов-оберток. - Закомментированная строка показывает, что нельзя присвоить
nullпримитивному типуboolean. Если вы раскомментируете эту строку и попытаетесь скомпилировать программу, получите ошибку компиляции.
- Мы объявляем примитивный тип
Сохраните файл (Ctrl+S или Cmd+S).
Откройте терминал внизу WebIDE. Убедитесь, что вы находитесь в директории
~/projectс помощью командыcd ~/project.Скомпилируйте Java-программу, введя следующую команду и нажав Enter:
javac PrimitiveVsWrapper.javaЕсли нет ошибок, будет создан файл
PrimitiveVsWrapper.class.Запустите скомпилированную программу с помощью следующей команды и нажмите Enter:
java PrimitiveVsWrapperВы должны увидеть следующий вывод:
Primitive boolean value: true Wrapper Boolean is null
Этот вывод четко показывает, что примитивный тип boolean содержит значение (true), в то время как объект обертки Boolean может быть равен null. Это различие важно при проектировании Java-программ и обработке потенциально отсутствующих значений.
Резюме
В этом практическом занятии (лабораторной работе) мы научились обрабатывать потенциальные значения null при работе с объектами Boolean в Java. Мы увидели, что в отличие от примитивных типов boolean, обертка Boolean может быть равна null, что может привести к ошибкам NullPointerException. Мы продемонстрировали правильный способ проверки, не является ли объект Boolean равным null перед доступом к его булевому значению, используя проверку != null в сочетании с логическим оператором И (&&). Это гарантирует, что булево значение вычисляется только в том случае, если объект не равен null, предотвращая ошибки времени выполнения.



