Optional

2024. 4. 24. 00:51자바

업무를 할 때 데이터베이스에서 데이터를 조회 후, 반환된 데이터가 null인 경우에 대비해서 if문으로 null 체크를 수행하고, 이에 따른 로직을 처리해 왔습니다.

물론 그에 따른 테스트를 진행하지만, 이러한 방식은 가독성도 떨어지고 혹시 모를 실수에 대비가 안된다는 점이 불안했습니다.

그래서 대안을 찾아보던 중 Optional에 대해서 알게 되어 이를 적용하면서 알아본 내용을 정리하겠습니다.

 

Optional이란?

Optional은 Java 8에서 소개된 클래스로, 값이 존재하지 않을 수 있는 경우에 대해서 처리할 수 있는 클래스입니다.

Optional은 NPE(NullPointerException)을 방지하고, 코드를 더 명확하게 만들어주는 Wrapper 클래스입니다.

 

 

 

적용 예시

// 데이터베이스에서 사용자 정보를 조회하는 메서드
public User findUserById(Long userId) {
    // userId에 해당하는 사용자를 데이터베이스에서 조회하여 반환
    // 만약 사용자가 존재하지 않는 경우, null을 반환
}

// Optional을 사용하지 않는 경우
public String getUserNameWithoutOptional(Long userId) {
    User user = findUserById(userId);
    if (user != null) {
        return user.getName();
    } else {
        throw new RuntimeException("사용자를 찾을 수 없습니다. userId: " + userId);
    }
}

// Optional을 사용하는 경우
public String getUserNameWithOptional(Long userId) {
    Optional<User> userOptional = Optional.ofNullable(findUserById(userId));
    return userOptional.map(User::getName)
                        .orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다. userId: " + userId));
}

 

위의 findUserById를 제외한 두 메서드는 같은 결과를 반환하지만, Optional을 사용하는 경우가 더 간결하고 명확합니다.

 

 

 

Optional의 주요 메서드

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Optional.html

 

Optional (Java SE 11 & JDK 11 )

If a value is present, returns the result of applying the given Optional-bearing mapping function to the value, otherwise returns an empty Optional. This method is similar to map(Function), but the mapping function is one whose result is already an Optiona

docs.oracle.com

 

isPresent()

Optional에 값이 존재하는지 확인합니다. 값이 존재하는 경우 true를 반환하고, 값이 없는 경우 false를 반환합니다.

Optional<String> optional = Optional.of("Hello");
boolean isPresent = optional.isPresent(); // true

 

ifPresent(Consumer)

값이 존재하는 경우에만 해당 값을 가지고 작업을 수행합니다.

Consumer 함수형 인터페이스를 인자로 받으며, 해당 함수를 실행합니다.

Optional<String> optional = Optional.of("Hello");
optional.ifPresent(value -> System.out.println("Value is present: " + value));

 

get()

Optional에 값이 존재하는 경우 해당 값을 반환합니다.

값이 없는 경우 NoSuchElementException을 발생시킵니다.

주의할 점은 이 메서드를 호출하기 전에 isPresent()를 사용하여 값의 존재 여부를 확인해야 합니다.

Optional<String> optional = Optional.of("Hello");
String value = optional.get(); // "Hello"

 

orElse(T)

값이 존재하는 경우 해당 값을 반환하고, 값이 없는 경우 지정된 기본값을 반환합니다.

Optional<String> optional = Optional.empty();
String value = optional.orElse("Default Value"); // "Default Value"

 

orElseGet(Supplier)

값이 존재하는 경우 해당 값을 반환하고, 값이 없는 경우 Supplier에서 제공하는 대체 값을 반환합니다.

Optional<String> optional = Optional.empty();
String value = optional.orElseGet(() -> "Default Value"); // "Default Value"

 

orElseThrow(Supplier)

값이 존재하는 경우 해당 값을 반환하고, 값이 없는 경우 Supplier에서 제공하는 예외를 발생시킵니다.

Optional<String> optional = Optional.empty();
String value = optional.orElseThrow(() -> new NoSuchElementException("Value is not present"));

 

 

 

 

주의점

Optional은 설계에서 좋은 선택이지만 사용할 때 주의점이 있습니다.

 

  • 성능에 민감한 경우
    Optional은 객체를 감싸는 추가적인 래퍼이므로 성능에 안 좋은 영향을 미칠 수 있습니다.
    성능에 민감한 상황이라면 이 부하를 고려해야 합니다.
  • 너무 남발하는 경우
    모든 상황에서 Optional을 사용한다고 해서 코드가 더 깔끔해지지 않습니다.
    오히려 너무 많은 곳에서 Optional을 남발한다면 코드를 더 복잡하게 만들 수 있습니다.
    Optional을 사용할 때는 실제로 값이 없을 때만 사용하는 것이 좋습니다.

이 외의 주의할 점들이 더 있습니다.

제가 참고한 블로그 링크를 공유하며 글 마치겠습니다.
https://mangkyu.tistory.com/203

 

[Java] 언제 Optional을 사용해야 하는가? 올바른 Optional 사용법 가이드 - (2/2)

앞선 포스팅에서는 Optional의 개념과 문법을 살펴보았습니다. Optional은 Null이 될 수 있는 객체를 감싸는 Wrapper 클래스이기 때문에 비용이 발생합니다. 그래서 Optional은 필요한 경우에만 사용하는

mangkyu.tistory.com

 

'자바' 카테고리의 다른 글

빌드(Build)  (0) 2024.06.17
[JVM] Class Loader  (0) 2024.04.18
[JVM] Garbage Collector  (0) 2024.04.18
[JVM] Runtime Data Area  (0) 2024.04.18
[JVM] JVM 이란  (0) 2024.04.18