Java8 Optional2

Date:     Updated:

카테고리:

태그:

Optional2

반환타입을 Optional로 사용

Optional을 반환하는 메서드 예시

  • 컬렉션에서 최대값을 구하는 메서드 - Optional 사용 X
public static <E extends Comparable<E>> E max(Collection<E> c) {
    if (c.isEmpty())
        throw new IllegalArgumentException("Empty collection");

    E result = null;
    for (E e : c)
        if (result == null || e.compareTo(result) > 0)
            result = Objects.requireNonNull(e);

    return result;
}
  • 컬렉션에서 최대값을 구하는 메서드 - Optional 사용
public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) {
    if (c.isEmpty())
        return Optional.empty();

    E result = null;
    for (E e : c)
        if (result == null || e.compareTo(result) > 0)
            result = Objects.requireNonNull(e);

    return Optional.of(result);
}
  • Optional을 반환할때는 제공해주는 정적 팩터리 메서드를 사용하면 간단하다.

Optional 반환 장점

  • Optional은 검사 예외와 취지가 비슷하다. 즉 메서드의 반환값이 없을 수도 있다는걸
    API 사용자에게 명확히 의미를 전달할 수 있다. Optional을 반환한다면 이를 호출하는 클라이언트에서는 반드시 이에 대처하는 코드를 추가해야 한다.
    • 위에서 null을 반환하는경우 null 처리를 위한 코드가 필요하므로 Optional이 등장했다고 이야기 했는데,
      Optioanl도 이를 처리하는 코드가 필요하니까 똑같은거 아니냐 할 수 있지만 null에 비해 Optional은 명확한 의미전달 + 편리한 후처리 메서드 제공 + NPE 방지 등의 장점이 있다고 생각한다.

Optional 반환 좋은예, 나쁜예

  • 좋은예
    • 위에서도 말했듯이 결과가 없을 수 있는 경우
    • 클라이언트가 이 상황을 특별하게 처리해야 하는 경우
  • 나쁜예
    • 반환값으로 Optional을 사용한다고 무조건적으로 좋지 않다.
      • Optional도 새로 할당하고 초기화해야하는 객체이고, Optional에서 값을 꺼내기 위해선 메서드를 호출해야 하니 이것 또한 비용이다. 성능이 중요한 상황에서는 Optional이 맞지 않을 수 있다.

Optional 주의사항

  • Collection, Stream, Array, Optional 같은 컨테이너 타입은 Optional로 감싸면 안된다.
    • Optioanl보다는 그냥 빈 List를 반환하는게 더 좋다. 빈 List를 반환하면 이를 호출하는 클라이언트에서는 Optional 처리 코드가 필요 없다.
  • Map의 값으로 Optional을 사용하면 절대 안된다.
    • Map 안에 키가 없다는 사실을 나타내는 방법이 두가지가 된다.
      • 키 자체가 없는 경우
      • 키는 있지만 Optional인 경우
    • 이로 인해 복잡성만 증가하고 오류 가능성을 키울 뿐이다.
    • 좀더 일반화 한다면 Optional을 컬렉션의 키, 값, 원소나 배열의 원소로 사용하는게 적정한 상황은 거의 없다.
  • 인스턴스의 필드에 Optional 사용
    • 이런 상황 대부분은 필수 필드를 갖는 클래스와, 이를 확장해 선택적 필드를 추가한 하위 클래스를 따로 만들어야함을 암시하는 좋지않은 신호이다.
    • 가끔 필드에 Optional을 사용하기 좋은 예외상황도 있다.
      • 인스턴스의 필드 중 필수가 아니고, primitive 타입이라 값이 없음을 나타낸 방법이 마땅하지 않은 경우이다.

트레이드 오프

  • Optioanl또한 새로 할당하고 초기화해야 하는 객체이고, Optional에서 값을 꺼내려면 메서드를 호출해야 한다. 이로 인해 성능이 중요한 상황에서는 알맞지 않을 수 있다. 라고 한다.
  • 하지만 이펙티브 자바 Item6 에서도 다룬 내용으로 “요즘 JVM에서 작은 객체를 생성하고 회수하는 일은 크게 부담되지 않는다. “ 라는 말이 있다.
  • 즉 Optional이 가져다주는 이점을 따져보면, 성능때문에 Optional 사용을 지양하자 라는 이야기는 알맞지 않다.

정리

💡 값을 반환하지 못할 가능성이 있고, 호출할 때마다 반환값이 없을 가능성을 염두에 둬야 하는 메서드라면 Optional을 반환하는걸 고려하자.

Optional 반환에는 성능저하가 뒤따르니 남용하지말자. 하지만 Optioanl을 반환함으로써 얻는 이점이 많으니 사용하는걸 지향하고자한다.

Optional을 반환값 이외의 용도로 사용하는 경우는 거의 없다.

Java 카테고리 내 다른 글 보러가기

댓글남기기