Skip to content

Latest commit

 

History

History
105 lines (82 loc) · 3.33 KB

옵셔널_반환은_신중히_하라.md

File metadata and controls

105 lines (82 loc) · 3.33 KB

아이템 55 : 옵셔녈 반환은 신중히 하라


핵심 정리

  • Optional은 반환값이 없을 수 있으며 클라이언트가 이를 대비해야 할 때 사용하라
  • 컬렉션을 Optional로 감싸기보다 빈 컬렉션을 반환하라
  • 꽤 비싼 객체이다
  • 옵셔녈을 컬렉션의 키, 값, 원소나 배열의 원소로 사용하지 마라

등장 배경

자바 8이전 값을 반환할 수 없을 때, 2가지 선택지

  1. 예외 반환 => 문제 : stack 캡처 고비용 / 진짜 예외 상황이 아닐 수 있음
  2. null 반환 => 문제 : 클라에서 null 처리 필요 => 반환값이 없을 수도 있음을 API 사용자에게 알려주는 효율적 기능이 필요!

Optional 사용의 기준

- 결과가 없을 수 있음
- 클라이언트가 이 상황을 특별히 처리해야 함

옵셔널 사용 예시

ex) 컬렉션에 원소가 없을 때

  • before :예외 반환
 public static <E extends Comparable<E>> E max1(Collection<E> c) {
    if (c.isEmpty())
        throw new IllegalArgumentException("Empty collection");
    ...
}
  • after : Optional empty 반환
 public static <E extends Comparable<E>> 
    Optional<E> max2(Collection<E> c) {
        if (c.isEmpty())
            return Optional.empty();
    ...
    }

Optional 사용 주의사항

1. 옵셔널을 반환하는 메서드에서는 null을 반환하지 마라

  • Optional을 도입한 취지를 무시하는 행위다

2. 컨테이너 타입은 옵셔널로 감싸지 마라

  • 컨테이너 타입 : 컬렉션, 스트림, 배열, 옵셔널
  • Optional<List>가 아닌 빈 List를 반환하라

3. 성능이 느려질 수 있다

  • 한번 래핑하는 과정의 비용이 있을 수 밖에 없다
  • 박싱된 기본 타입을 담은 옵셔녈 반환을 지양하라(Integer, Long, Double)
  • 미리 준비되어 있다 => OptionalInt, OptionalLong, OptionalDouble

4. 옵셔녈을 컬렉션의 키, 값, 원소나 배열의 원소로 사용하지 마라

  • 혼란과 오류 가능성을 높인다
  • ex) 맵의 value로 Optional을 사용 > 키가 없음을 나타내는 맥락이 2개가 됨(키가 없을 때, 옵셔녈 반환할 때)

옵셔널 활용 방법

  1. orElse : 기본 값 반환
String lastWordLexicon = max(words).orElse("단어 없음...");
  1. orElseThrow(Supplier<? extends Exception> exceptionSupplier) : 없으면 예외 반환
Toy myToy = max(toys).orElseThrow(IllegalArgumentException::new);
  1. orElseGet(Supplier<? extends T> other) : emtpy이면 => Supplier를 통한 값 반환
  2. ifPresent(Consumer<? super T) consumer) : 값이 존재할 때 인수로 넘겨준 동작 실행
  3. ifPresentOrElse(Consumer<? super T> consumer, Runnable, emptyAction) : Optional이 비었을 때 실행가능한 Runnable

Optional의 stream 연산

  • Optional은 stream 연산이 가능하다
  • 여러 연산이 있지만 그 중 map 연산만 잘 이해하고 넘어가자
  • map은 마치 다음과 같은 의미로 사용된다 : 있으면 수행하라
  • 없으면 아무 일도 일어나지 않는다
Optional<People> people = Optional.ofNullable(null);
if(people.isPresent()) {
    name = people.get().getName();
}
Optional<People> people = Optional.ofNullable(null);
Optional<String> name = people.map(People::getName);;