Backend/Java

Optional

간지나제 2021. 4. 27. 08:27

Optional은 null값을 다룰 수 있는 class로 주로 null과 관련된 로직에 사용하면 편리하고 좋다. (Java는 8버전부터 도입)

  • NPE(Null Pointer Exception) 방지
  • null이 나올 수 있다는 것을 명시적으로 알려줌
  • null을 직접 다루지 않아 코드가 간결해지고 가독성이 좋아진다.

예를 들어 보자.
Order class에 name이라는 변수가 있고 그 값을 정하지 않은 상태라고 하자.

public class OptioanlTest {

    public static void main(String[] args) {
        Order order = new Order();
        String name = order.getName(); => name에는 null값
        String comp = “test”;
        if(name.equals(comp)) { // NPE 발생
            System.out.println(“같음”);  
        }
    }
}

위와 같이 name값이 정해지지 않은 상태에서 comp값과 비교를 하려고 하니 NPE가 발생한다.
이럴 경우 보통 null check를 해주기 위해

if(name != null) {
    ...
}

이런식으로 사용할 것이다.
이런식으로 조건문으로 사용하는 것보다

String name = Optional.ofNullable(order).map(Order::getName).orElse(“”);

이런식으로 null-safe한 코드를 만들 수 있고 null일 때는 원하는 값으로 설정할 수 있다. 매번 조건문으로 하는 것은 지저분한 코드를 만들 수 있기 때문에 Optional을 사용하는게 훨씬 가독성이 좋아보인다.

또, 다른 경우는 null을 반환하지 않고 바로 Exception을 던져버리는 경우도 있다.

List<String> cities = Arrays.asList(“Seoul”, “Daegu”, “Busan”);

String city = null;
cities.get(3); => Exception 발생!

이런 경우는 거의 없겠지만 만약 이런 경우라면 try-catch로 감싸줘서 해결할 것이다.
하지만 이런 경우에도 정적 유틸리티를 이용하여 좀 더 가독성 있는 코드로 만들 수 있는데

public static <T> Optional<T> getAsOptional(List<T> list, int index) {
    try {
        return Optional.of(list.get(index));
    } catch(ArrayIndexOutOfBoundsException e) {
        return Optioanl.empty();
    }
}
Optional<String> city = getAsOptional(cities, 3);
int length = city.map(String::length).orElse(0); // null-safe

이런 식으로 이미 내부적으로 try-catch가 되어 있는 static method인 getAsOptonal을 호출함으로써 Optional을 리턴받고 null-safe한 코드까지 작성할 수 있다.

https://www.daleseo.com/java8-optional-after/
https://advenoh.tistory.com/15