본문 바로가기

자바의 정석

[자바의 정석 2권] Optional

 

1) Optional<T>와 OptionalInt

- Optional<T>는 지네릭 클래스로 'T타입의 객체'를 감싸는 래퍼 클래스이다.

  그래서 Optional 타입의 객체에는 모든 타입의 참조변수를 담을 수 있다. 

public final class Optional<T> {
	private final T value; // T타입의 참조변수
}

 

- 최종 연산의 결과를 그냥 반환하는 게 아니라 Optional객체에 담아서 반환하는 것이다.

  이처럼 객체에 담아서 반환을 하면, 반환된 결과가 null인지 매번 if문으로 체크하는 대신

  Optional에 정의된 메서드를 통해서 간단히 처리할 수 있다. 

 

- 이제 널 체크를 위한 if문 없이도 NullPointerException이 발생하지 않는

  보다 간결하고 안전한 코드를 작성하는 것이 가능해진 것이다. 

 


2) Optional 객체 생성하기

- Optional 객체를 생성할 때는 of() 또는 ofNullable()을 사용한다.

String str = "abc";
Optional<String> optVal = Optional.of(str);
Optional<String> optVal = Optional.of("abc");
Optional<String> optVal = Optional.of(new String("abc"));

 

- 만일 참조변수의 값이 null일 가능성이 있으면, of() 대신 ofNullable()을 사용해야 한다.

  of()는 매개변수의 값이 null이면 NullPointerException이 발생하기 때문이다. 

Optional<String> optVal = Optional.of(null); // NullPointerException 발생
Optional<String> optVal = Optional.ofNullable(null); // OK

 

- Optional<T> 타입의 참조변수를 기본값으로 초기화할 때는 empty()를 사용한다.

  null로 초기화하는 것이 가능하지만, empty()로 초기화하는 것이 바람직하다. 

Optional<Stirng> optVal = null; // 널로 초기화
Optional<String> optVal = Optional.<String>empty(); // 빈 객체로 초기화

 

 

3) Optional 객체의 값 가져오기

- Optional 객체에 저장된 값을 가져올 때는, get()을 사용한다.

  값이 null일때는 NoSuchElementException이 발생하며, 이를 대비해서 orElse()로 대체할 값을 지정할 수 있다. 

Optional<String> optVal = Optional.of("abc");
String str1 = optVal.get(); // optVal에 저장된 값을 반환. null이면 예외 발생
String str2 = optVal.orElse(""); // optVal에 저장된 값이 null일 때는, ""를 반환

 

- orElse()의 변형으로는 null을 대체할 값을 반환하는 람다식을 지정할 수 있는 orElseGet()과 

  null일 때 지정된 예외를 발생시키는 orElseThrow()가 있다. 

T orElseGet(Supplier<? extends T> other)
T orElseThrow(Supplier<? extends X> exceptionSupplier)

 

- 사용하는 방법은 아래와 같다. 

String str3 = optVal2.orElseGet(String::new); // () -> new String()와 동일
String str4 = optVal2.orElseThrow(NullPointerException::new); // 널이면 예외 발생