woowacourse-study / 2022-modern-java-in-action

우아한테크코스 4기 모던 자바 인 액션 스터디
10 stars 4 forks source link

Optional을 사용해야 하는 적절한 경우는 언제일까? #42

Open jaejae-yoo opened 2 years ago

jaejae-yoo commented 2 years ago

문제

책에서 소개하고 있는 Optional을 사용해야 하는 적절한 경우는 언제일까?

선정 배경

책의 내용에서 값을 반환하지 않을 가능성이 있는 경우에는, Optional을 통해 해결할 수 있다고 설명하고 있다. 그렇다면 '반환 값이 없을 가능성이 있는 모든 경우에는 Optional을 사용하는 것이 옳을까?'라는 궁금증이 생겨 주제로 선정하였습니다.

관련 챕터

[5장] 스트림 활용 168p

jaejae-yoo commented 2 years ago

책의 내용을 보면 반환 값이 없을 때 null을 반환하는 것은 쉽게 에러를 반환할 수 있기 때문에, 자바 8에서 값의 부재를 표현하는 컨테이너 클래스인 Optional이 만들어졌다고 나와있습니다.

자바 8 이전에는 메서드가 특정 조건에서 값을 반환할 수 없을 때, 선택할 수 있는 두 가지의 옵션이 있었습니다. 예외를 던지거나, null을 반환하는 두 가지의 방법입니다.

이 두 가지 방법 모두 문제가 있는데요. 먼저 예외는 정말 예외 상황인 경우에만 사용해야 하고, null을 반환하는 메서드의 경우에는 별도의 null 처리를 추가(아니면 Null Pointer Exception이 발생할 수 있다.)해야 한다는 문제가 있습니다.

이후 자바 8에서 Optional이라는 새로운 선택지를 선택할 수 있게 되었습니다. Optional을 사용하면  위의 단점을 보완하며 아무것도 담지 않을 수가 있습니다. Optional을 반환하는 메서드는 예외를 던지는 메서드보다 유연하고 사용하기 쉬우며, null을 반환하는 메서드보다 오류 가능성이 적습니다.

Optional은 검사 예외와 취지가 유사합니다. 즉, 반환값이 없을 수도 있음을 API 사용자에게 명확히 알려줘야 할 때 사용할 수 있습니다.

Optinal의 이점

  1. 기본값을 정할 수 있다.
return apples.stream()
         .filter(Fruit::isRed)
         .findAny()
         .orElse(green);
  1. 원하는 예외를 던질 수 있다.
return apples.stream()
        .filter(Fruit::isRed)
        .findAny()
        .orElseThrow(원하는 예외);

Optional을 사용하는 것이 항상 좋은 것은 아니다.

  1. 컬렉션, 스트림, 배열, 옵셔널과 같은 컨테이너는 또 Optional로 감싸지 말아야 한다.
    • 빈 Optional <List >를 반환하기보다는 빈 List 를 반환하는 게 좋다. (클라이언트가 Optional 처리 코드를 넣지 않아도 된다.)
  2. 박싱 된 기본 타입을 Optional로 반환하지 않도록 하자.
    • 기본 타입을 감싸서 Optional로 또 감싼다면 2겹으로 감싸게 된다. 성능상에 문제가 있을 수 있다. 자바 API에는 int, double, long 전용 Optional 클래스를 만들었다. (OptionalInt, OptionalDouble,OptionalLong)
  3. Optional을 컬렉션의 Key, Value, 혹은 배열의 Element로 사용하지 말자.
    • 복잡성만 높여 혼란과 오류 가능성을 키운다. (맵 안에 key가 없는 경우: key 자체가 없는 경우, key가 빈 Optional인 경우)