1. Optional<T>
- JDK 1.8(Java 8)에서 도입된 새로운 타입입니다.
- 해당 타입은 값을 반환할 수 없는 상황에서
null
등을 반환해야 할 때 사용할 수 있습니다.
- 해당 타입이 나오기 이전에는 다음과 같은 2가지 방법이 있었습니다.
- 두 방법 모두 문제가 있습니다.
- 예외는 정말 예외적인 경우에만 생성하여 던져야 합니다. 또한 예외를 생성할 때 스택 추적 전체를 가져와야 하기 때문에 비용 또한 작지 않습니다.
null
을 반환하면 위와 같은 상황은 일어나지 않으나 해당 메서드를 사용하는 클라이언트에서 null
이 반환되는 것에 대한 방어적 코드를 작성해야 합니다.
Optional<T>
를 사용할 경우 값이 존재한다면 T
타입 참조값을 하나 넣고, 그렇지 않을 경우 아무것도 담지 않을 수 있습니다.
- 이때 아무것도 담지 않은
Optional
은 비어있다 라고 합니다.
Optional
은 그 자체로는 Collection
을 구현하지 않았지만 원소를 최대 1개 가질 수 있는 불변 컬렉션이라고 할 수 있습니다.
2. 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.empty()
를 사용하여 만들 수 있습니다.
- 그렇지 않은 경우
Optional.of()
를 사용하여 만들 수 있습니다. 만약 null
도 허용하는 Optional
을 만들고 싶다면 Optional.ofNullable()
을 사용하면 됩니다.
- 이런
Optional
을 반환하는 메서드에는 절대 null
을 반환하면 안되며 이런 방식은 Optional
을 도입하는 취지를 완전히 무시하는 행위라고 서술되어 있습니다.
3. Optional과 Stream
- 스트림에서 많은 수의 종단 연산이
Optional
을 반환합니다.
- 위에 적었던 최대값을 연산하는 코드를
Stream
을 사용한 코드는 다음과 같습니다.
public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) {
return c.stream().max(Comparator.naturalOrder());
}