Java 에서 Integer 객체가 Null 인지 확인하는 방법

JavaBeginner
지금 연습하기

소개

이 랩에서는 Java 에서 Integer 래퍼 객체를 안전하게 처리하는 방법을 배우게 됩니다. 특히, null인지 확인하는 데 중점을 둡니다. 기본형 int와 달리, Integernull 참조를 가질 수 있는 객체이며, null을 확인하지 않으면 흔한 NullPointerException 오류가 발생할 수 있습니다.

실용적인 예제를 통해 기본적인 == null 검사를 살펴보고, null 검사를 값 비교와 결합하며, 마지막으로 Java 코드에서 더 강력하고 표현력 있는 null 처리를 위해 Optional 클래스를 활용하는 방법을 배우게 됩니다.

Integer 래퍼 Null 여부 테스트

이 단계에서는 Java 에서 Integer 래퍼 객체를 처리하는 방법을 살펴보고, 특히 null인지 확인하는 데 중점을 둡니다. int와 같은 기본형과 달리, Integer는 클래스이므로 Integer 변수는 객체에 대한 참조를 가질 수 있으며, 어떤 객체도 참조하지 않으면 null이 될 수 있습니다. null 값을 처리하는 것은 Java 에서 매우 흔하고 프로그램 충돌을 일으킬 수 있는 NullPointerException 오류를 방지하는 데 매우 중요합니다.

Integernull을 확인하는 것을 보여주는 간단한 Java 프로그램을 만들어 보겠습니다.

  1. WebIDE 편집기에서 HelloJava.java 파일을 엽니다. 이전 랩을 완료했다면 이 파일은 이미 ~/project 디렉토리에 존재해야 합니다.

  2. HelloJava.java의 기존 코드를 다음으로 바꿉니다.

    public class HelloJava {
        public static void main(String[] args) {
            Integer myInteger = null; // Integer 를 선언하고 null 로 설정
    
            // myInteger 가 null 인지 확인
            if (myInteger == null) {
                System.out.println("myInteger is null.");
            } else {
                System.out.println("myInteger is not null. Its value is: " + myInteger);
            }
    
            // null 이 아닌 Integer 로 시도해 봅시다.
            Integer anotherInteger = 10; // 값을 선언하고 초기화
    
            // anotherInteger 가 null 인지 확인
            if (anotherInteger == null) {
                System.out.println("anotherInteger is null.");
            } else {
                System.out.println("anotherInteger is not null. Its value is: " + anotherInteger);
            }
        }
    }

    이 코드에서:

    • Integer 변수 myInteger를 선언하고 명시적으로 null로 설정합니다.
    • == 연산자를 사용하여 myIntegernull과 같은지 확인하기 위해 if 문을 사용합니다. 이것은 Java 에서 객체 참조가 null인지 확인하는 표준 방법입니다.
    • 그런 다음 다른 Integer 변수 anotherInteger를 선언하고 값 10을 할당합니다. Java 는 기본형 int10Integer 객체로 자동 변환합니다 (이것을 오토박싱 (autoboxing) 이라고 합니다).
    • anotherInteger에 대해 동일한 null 검사를 수행합니다.
  3. HelloJava.java 파일을 저장합니다 (Ctrl+S 또는 Cmd+S).

  4. 이제 터미널에서 javac 명령을 사용하여 프로그램을 컴파일합니다. ~/project 디렉토리에 있는지 확인하십시오.

    javac HelloJava.java

    오류가 없으면 컴파일이 조용히 완료되고 HelloJava.class 파일이 ~/project 디렉토리에 생성됩니다.

  5. java 명령을 사용하여 컴파일된 프로그램을 실행합니다.

    java HelloJava

    다음과 유사한 출력을 볼 수 있습니다.

    myInteger is null.
    anotherInteger is not null. Its value is: 10

    이 출력은 null Integernull이 아닌 Integer 모두에 대해 null 검사가 올바르게 작동했음을 확인합니다. null을 확인하는 방법을 이해하는 것은 Java 프로그래밍, 특히 래퍼 클래스와 항상 값이 할당되지 않을 수 있는 객체를 다룰 때 기본적인 기술입니다.

Null 및 값 검사 결합

이전 단계에서는 Integer 객체가 null인지 확인하는 방법을 배웠습니다. 종종 Integernull이 아니고 해당 값이 특정 조건을 충족하는지 확인해야 합니다. 이러한 검사를 결합하는 것은 null Integer의 값에 접근하려고 하면 NullPointerException이 발생하기 때문에 중요합니다.

null 검사를 값 검사와 결합하는 것을 보여주기 위해 프로그램을 수정해 보겠습니다.

  1. WebIDE 편집기에서 HelloJava.java 파일을 엽니다.

  2. 기존 코드를 다음으로 바꿉니다.

    public class HelloJava {
        public static void main(String[] args) {
            Integer score = null; // 예시 1: score 는 null
    
            // score 가 null 이 아니고 값이 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; // 예시 2: score 는 75
    
            // anotherScore 가 null 이 아니고 값이 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; // 예시 3: score 는 40
    
            // yetAnotherScore 가 null 이 아니고 값이 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.");
            }
        }
    }

    이 업데이트된 코드에서:

    • 논리 AND 연산자 (&&) 를 사용하여 두 조건 score != nullscore > 50을 결합합니다.
    • score != null 검사가 먼저 배치됩니다. Java 에서 && 연산자는 단락 평가를 사용합니다. 즉, 첫 번째 조건 (score != null) 이 false 이면 두 번째 조건 (score > 50) 은 평가되지 않습니다. 이렇게 하면 scorenull일 때 NullPointerException이 방지됩니다. 왜냐하면 코드 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.

    이 출력은 결합된 검사가 어떻게 작동하는지 보여줍니다. 첫 번째 경우는 scorenull임을 올바르게 식별합니다. 두 번째 경우는 anotherScorenull이 아니고 50 보다 크다는 것을 식별합니다. 세 번째 경우는 yetAnotherScorenull이 아니더라도 50 보다 크지 않다는 것을 식별합니다. 객체의 속성이나 값에 접근하기 전에 null을 확인하는 이 패턴은 Java 에서 기본적인 안전 관행입니다.

안전한 처리를 위한 Optional 사용

== null을 사용하여 null을 확인하고 &&로 검사를 결합하는 것이 효과적이지만, Java 8 은 부재할 수 있는 값 (즉, null) 을 처리하는 더 관용적인 방법으로 Optional 클래스를 도입했습니다. Optionalnull이 아닌 값을 포함할 수도 있고 포함하지 않을 수도 있는 컨테이너 객체입니다. Optional을 사용하면 코드를 더 읽기 쉽고 NullPointerException 오류가 발생할 가능성을 줄일 수 있습니다.

이 단계에서는 잠재적으로 부재하는 정수 값을 처리하기 위해 Optional<Integer>를 사용하도록 프로그램을 리팩터링합니다.

  1. WebIDE 편집기에서 HelloJava.java 파일을 엽니다.

  2. 기존 코드를 다음으로 바꿉니다.

    import java.util.Optional;
    
    public class HelloJava {
        public static void main(String[] args) {
            // 예시 1: null 값을 포함하는 Optional (empty Optional)
            Optional<Integer> optionalScoreNull = Optional.empty();
    
            // Optional 에 값이 있는지, 그리고 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.");
            }
    
            // 예시 2: null 이 아닌 값을 포함하는 Optional (75)
            Optional<Integer> optionalScorePresent = Optional.of(75);
    
            // Optional 에 값이 있는지, 그리고 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.");
            }
    
            // 예시 3: null 이 아닌 값을 포함하는 Optional (40)
            Optional<Integer> optionalScoreNotGreater = Optional.of(40);
    
            // Optional 에 값이 있는지, 그리고 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.");
            }
    
            // Optional 메서드를 사용하는 더 기능적인 방법
            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));
    
            // Optional 이 비어 있는 경우 기본값을 제공하기 위해 orElse 사용
            Integer scoreOrDefault = optionalScoreNull.orElse(0);
            System.out.println("Value from optionalScoreNull with default: " + scoreOrDefault);
    
            // 조건부 검사를 위한 filter 사용
            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.of()를 사용하여 null이 아닌 값을 포함하는 Optional을 만듭니다. Optional.of()null 값을 전달하면 NullPointerException이 발생합니다. 값이 null일 수 있는 경우 Optional.ofNullable()을 사용하십시오.
    • optionalScoreNull.isPresent(): 이 메서드는 Optional에 값이 있는지 확인합니다. null을 확인하는 대신 존재 여부를 확인하는 것이 좋습니다.
    • optionalScoreNull.get(): 이 메서드는 Optional에서 값을 검색합니다. 주의하세요! Optional이 비어 있으면 get()을 호출하면 NoSuchElementException이 발생합니다. 따라서 get()을 호출하기 전에 항상 isPresent()를 확인하거나, 빈 경우를 적절하게 처리하는 다른 Optional 메서드를 사용해야 합니다.
    • optionalScoreNull.ifPresent(value -> ...): 이 메서드는 Optional에 값이 있는 경우에만 제공된 코드를 실행합니다. 값이 있는 경우 해당 값에 대해 작업을 수행하는 깔끔한 방법입니다.
    • optionalScoreNull.orElse(0): 이 메서드는 값이 있으면 값을 반환하고, 그렇지 않으면 지정된 기본값 (이 경우 0) 을 반환합니다.
    • optionalScorePresent.filter(value -> value > 50): 이 메서드는 값이 있고 주어진 조건 (value > 50) 과 일치하는 경우 값을 포함하는 Optional을 반환하고, 그렇지 않으면 빈 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 개발에서 좋은 관행입니다.

요약

이 Lab 에서는 Java 에서 Integer 래퍼 객체가 null인지 확인하는 방법을 배웠습니다. 먼저 Integer가 클래스이며 기본형 int와 달리 null 참조를 가질 수 있다는 것을 이해했습니다. 간단한 Java 프로그램을 사용하여 기본 == null 검사를 시연하여 NullPointerException을 방지하기 위해 nullnull이 아닌 Integer 변수를 모두 처리하는 방법을 보여주었습니다.