1. Optional 소개


<aside> 💡 오직 값 한 개가 들어있을 수도 없을 수도 있는 컨테이너

</aside>

등장배경

java 8 이전 에 null check를 했던 방식을 먼저 코드를 통해 살펴보자.

위와같이 수업의 진행상황정보 객체(Progress)와 수업객체(OnlineClass)가 있다고할 때

public static void main(String[] args) {
    List<OnlineClass> springClasses = new ArrayList<>();
    springClasses.add(new OnlineClass(1, "spring boot", true));
    springClasses.add(new OnlineClass(2, "spring data jpa", true));
    springClasses.add(new OnlineClass(3, "spring mvc", false));
    springClasses.add(new OnlineClass(4, "spring core", false));
    springClasses.add(new OnlineClass(5, "rest api development", false));

    OnlineClass spring_boot = new OnlineClass(1, "spring boot", true);
    Duration studyDuration = spring_boot.getProgress().getStudyDuration();
    System.out.println("studyDuration = " + studyDuration);
}

이렇게 특정 수업의 진행상황정보를 조회하면 제대로 조회가될까요?

당연히, Progress에는 값이 설정되지 않았기 때문에 NullPointException이 발생을 합니다.

그래서 java 8 이전에는 이런 Exception을 막기위해 아래와 같이 로직을 구현했습니다.

public static void main(String[] args) {
    OnlineClass spring_boot = new OnlineClass(1, "spring boot", true);
    Progress progress = spring_boot.getProgress();
    if (progress != null) {
        System.out.println(progress.getStudyDuration());    
    }
}

⇒ getter로 progress를 가져와 해당 값이 null인지 if문으로 조회 후 null이 아니라면 출력합니다.

근데, 이런식의 코드는 문제가 발생할 여지가 많습니다. 우리는 기계가 아닌 인간이기에 실수를 하거나 코드를 누락할 수 있고 null-check와 같은 작은 유효성검사는 놓칠수 있습니다. 그렇기에 종종 NullPointException을 볼수밖에 없습니다. 이러한 원인을 더 파고들면 결국 null 값이 반환되기 때문인데 java 8 이전에는 이를 막을 방법이 딱히 없기에 if문으로 유효성 검사를 하는수밖에 없었습니다.

아니면, 반환하는 측에서 해당 값이 null인 경우 의도적으로 Exception을 발생하는 수도 있지만, 이 역시 추천하기는 힘든 선택인게 에러 발생시 스택트레이스를 찍게되있고 이는 성능하락의 원인이 됩니다.

public Progress getProgress() {
    if (this.progress == null) {
        throw new IllegalStateException();
    }
    return progress;
}

Java 8 이후 Optional의 등장