Как проверить, является ли объект Integer равным null в Java

JavaJavaBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (лабораторной работе) вы научитесь безопасно работать с объектами-обёртками Integer в Java, с особым вниманием уделяя проверке на null. В отличие от примитивного типа int, Integer представляет собой объект, который может иметь null-ссылку, и если не проверить на null, это может привести к распространённым ошибкам NullPointerException.

С помощью практических примеров вы рассмотрите базовую проверку на == null, сочетание проверки на null с сравнением значений и, наконец, узнаете, как использовать класс Optional для более надежного и выразительного обработки null в вашем Java-коде.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java/BasicSyntaxGroup -.-> java/operators("Operators") java/BasicSyntaxGroup -.-> java/variables("Variables") java/BasicSyntaxGroup -.-> java/if_else("If...Else") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("Exceptions") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/wrapper_classes("Wrapper Classes") java/SystemandDataProcessingGroup -.-> java/object_methods("Object Methods") subgraph Lab Skills java/operators -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} java/variables -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} java/if_else -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} java/classes_objects -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} java/exceptions -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} java/wrapper_classes -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} java/object_methods -.-> lab-560008{{"Как проверить, является ли объект Integer равным null в Java"}} end

Проверка объекта-обёртки Integer на null

На этом этапе мы рассмотрим, как работать с объектами-обёртками Integer в Java, с особым вниманием уделяя проверке на null. В отличие от примитивных типов, таких как int, Integer представляет собой класс, что означает, что переменная типа Integer может хранить ссылку на объект или быть равной null, если она не ссылается на какой-либо объект. Обработка значений null является важной частью программирования на Java, чтобы избежать ошибок NullPointerException, которые очень распространены и могут привести к аварийному завершению программы.

Создадим простую Java-программу, которая демонстрирует проверку на null для объекта Integer.

  1. Откройте файл HelloJava.java в редакторе WebIDE. Если вы завершили предыдущую лабораторную работу (практическое занятие), этот файл должен уже существовать в директории ~/project.

  2. Замените существующий код в файле 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 автоматически преобразует примитивное значение int 10 в объект Integer (это называется автоупаковкой, autoboxing).
    • Выполняем ту же проверку на null для anotherInteger.
  3. Сохраните файл HelloJava.java (Ctrl+S или Cmd+S).

  4. Теперь скомпилируйте программу с помощью команды javac в терминале. Убедитесь, что вы находитесь в директории ~/project.

    javac HelloJava.java

    Если ошибок нет, компиляция пройдет без сообщений, и в директории ~/project будет создан файл HelloJava.class.

  5. Запустите скомпилированную программу с помощью команды 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 с проверкой значения.

  1. Откройте файл HelloJava.java в редакторе WebIDE.

  2. Замените существующий код следующим:

    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.
  3. Сохраните файл HelloJava.java.

  4. Скомпилируйте модифицированную программу в терминале:

    javac HelloJava.java
  5. Запустите скомпилированную программу:

    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> для обработки потенциально отсутствующих целочисленных значений.

  1. Откройте файл HelloJava.java в редакторе WebIDE.

  2. Замените существующий код следующим:

    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.
  3. Сохраните файл HelloJava.java.

  4. Скомпилируйте программу в терминале:

    javac HelloJava.java
  5. Запустите скомпилированную программу:

    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.