2024. 1. 3. 20:20ㆍBook/이펙티브 자바
자바 8 전에는 메서드가 특정 조건에서 값을 반환할 수 없을 때
1. 예외를 던지거나
2. 객체 참조라면 null 값을 반환한다.
예외는 진짜 예외적인 상황에서만 사용해야 하며 null을 반환할 때는 null 처리 코드를 추가해야 한다.
자바 8 이후에는 다른 선택지가 생겼다.
Optinal<T>는 null이 아닌 T타입 참조를 하나 담거나, 혹은 아무것도 담지 않을 수 있는 불변 컬렉션이다.
=> (컬렉션을 구현한 건 아니다.)
public static <E extends Comparable<E>> E max(Collection<E> c) {
if (c.isEmpty())
throw new IllegalArgumentException("빈 컬렉션");
E result = null;
for (E e : c)
if (result == null || e.compareTo(result) > 0)
result = Objects.requireNonNull(e);
return result;
}
이 메서드에 빈 컬렉션을 던지면 에러를 던진다. Optinal을 반환한 모습은 다음과 같다
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.empty()로 만들고, 값이 든 옵셔널은 Optional.of(value)를 사용하면 된다.
Optional.of(value)에서 null을 반환하면 에러가 발생한다. 이때는 Optional.ofNullable(value)를 사용할 수 있다. 하지만 옵셔널을 반환하는 메서드에서는 절대 null을 반환하지 말자. 그럼 쓰는 의미가 없다.
스트림의 종단 연산 중 상당수가 옵셔널을 반환한다.
public static <E extends Comparable<E>>
Optional<E> max(Collection<E> c) {
return c.stream().max(Comparator.naturalOrder());
}
예외나 null을 반환하는 대신 옵셔널을 반환하는 기준은 무엇일까?
결과가 없을 수 있으며, 클라이언트가 이 상황을 특별하게 처리해야 할 때이다. 클라이언트는 값을 받지 못했을때 취할 행동을 선택해야 한다.
API 사용자의 옵셔널 활용 1 - 기본값
String lastWordInLexicon = max(words).orElse("단어 없음...");
API 사용자의 옵셔널 활용 2 - 에러
String lastWordInLexicon = max(words).orElseThrow(IllegalAccessError::new);
API 사용자의 옵셔널 활용 3 - 항상 값이 채워져 있다고 가정.
String lastWordInLexicon = max(words).get();
기본값을 설정하는 비용이 커서 부담이 되는 상황에서는 Supplier<T>를 인수로 받는 orElseGet을 사용하면 된다.
반환값으로 옵셔널을 사용한다고 해서 무조건 좋은건 아니다. 컬렉션, 스트림, 배열, 옵셔널 같은 컨테이너 타입은 옵셔널로 감싸면 안된다. List<T>를 반환하는데 빈 값은 옵셔널로 감싸기보다는 빈 List<T>를 반환하는 게 낫다. 빈 컨테이너를 반환하면 클라이언트에 옵셔널 처리 코드를 넣지 않을 수 있다.
'Book > 이펙티브 자바' 카테고리의 다른 글
Item59 - 예외는 진짜 예외 상황에만 사용하라 (1) | 2024.01.11 |
---|---|
가변인수는 신중히 사용하라 (0) | 2023.12.31 |
Item52 - 다중정의는 신중히 사용하라 (0) | 2023.12.29 |
Item51 - 메서드 시그니처를 신중히 설계하라 (0) | 2023.12.28 |
Item50 - 적시에 방어적 복사본을 만들라 (0) | 2023.12.27 |