Java8 In Action 을 읽고 정리한 내용이다. java.util.Optional<T>
에 대해서 설명한다.
Optional 적용 패턴
Optional 객체 만들기
Optional
을 사용하려면 Optional
객체를 만들어야 한다. 다양한 방법으로 Optional
객체를 만들 수 있다.
빈 Optional
정적 팩토리 메서드 Optional.empty
로 빈 Optional
객체를 얻을 수 있다.
1 | Optional<Car> optionalCar = Optional.empty(); |
null이 아닌 값으로 Optional 만들기
정적 팩토리 메서드 Optional.of
로 null이 아닌 값을 포함하는 Optional
을 만들 수 있다.
1 | Optional<Car> optionalCar1 = Optional.of(car); |
car
가null
이면 즉시NullPointerException
이 발생한다.
null값으로 Optional 만들기
정적 팩토리 메서드 Optional.ofNullable
로 null값을 저장할 수 있는 Optional
을 만들 수 있다.
1 | Optional<Car> optionalCar2 = Optional.ofNullable(car); |
car
가null
이면 빈Optional(Optional.empty)
객체가 반환된다.
디폴트 액션과 Optional 언랩
Optional
클래스는 Optional
인스턴스에서 값을 읽을 수 있는 다양한 인스턴스 메서드를 제공한다.
get()
은 값을 읽는 가장 간단한 메서드면서 동시에 가장 안전하지 않은 메서드다. 메서드 get은 래핑된 값이 있으면 해당 값을 반환하고 값이 없으면NoSuchElementException
을 발생 시킨다. 따라서Optional
에 값이 반드시 있다고 가정할 수 있는 상황이 아니면 get 메서드를 사용하지 않는 것이 바람직하다.orElse(T other)
메서드를 이용하면Optional
이 값을 포함하지 않을 때 디폴트값으로 제공할 수 있다.orElseGet(Supplier<? extends T> other)
는orElse
메서드에 대응하는 게으른 버전의 메서드가.Optional
에 값이 없을 때만 Supplier가 실행되기 때문이다.orElseThrow(Supplier<? extends X> exceptionSupplier)
는Optional
이 비어있을때 예외를 발생시킨다는 점에서 get 메서드와 비슷하다. 하지만 이 메서드는 발생시킬 예외의 종류를 선택할 수 있다.ifPresent(Comsumer<? super T> comsumer)
를 이용하면 값이 존재할 때 인수로 넘겨준 동작을 실행할 수 있다. 값이 없으면 아무 일도 일어나지 않는다.
Optional 클래스의 메서드
메서드 | 설명 |
---|---|
empty | 빈 Optional 인스턴스 반환. |
filter | 값이 존재하며 프레디케이트와 일치하면 값을 포함하는 Optional을 반환하고, 값이 없거나 프레디케이트와 일치하지 않으면 빈 Optional을 반환함. |
flatMap | 값이 존재하면 인수로 제공된 함수를 적용한 결과 Optional을 반환하고, 값이 없으면 빈 Optional을 반환함. |
get | 값이 존재하면 Optional이 감싸고 있는 값을 반환하고, 값이 없으면 NoSuchElementException이 발생함. |
ifPresent | 값이 존재하면 지정된 Consumer를 실행하고, 값이 없으면 아무 일도 일어나지 않음. |
isPresent | 값이 존재하면 true를 반환하고, 값이 없으면 false를 반환함. |
map | 값이 존재하면 제공된 매핑 함수를 적용함. |
of | 값이 존재하면 값을 감싸는 Optional을 반환하고, 값이 null이면 NullPointerException을 발생함. |
ofNullable | 값이 존재하면 값을 감싸는 Optional을 반환하고, 값이 null이면 빈 Optional을 반환함. |
orElse | 값이 존재하면 값을 반환하고, 값이 없으면 디폴트값을 반환함. |
orElseGet | 값이 존재하면 값을 반환하고, 값이 없으면 Supplier에서 제공하는 값을 반환함. |
orElseThrow | 값이 존재하면 값을 반환하고, 값이 없으면 Supplier에서 생성한 예외를 발생함. |
Optional을 사용한 실용 예제
잠재적으로 null이 될 수 있는 대상을 Optional로 감싸기
Map 클래스의 get 메서드의 시그너처는 우리가 고칠 수 없지만 get 메서드의 반환값은 Optional로 감쌀 수 있다.
1 | // Before |
예외의 Optional
문자열을 정수 Optional로 변환
1 | public static Optional<Integer> stringToInt(String s) { |
응용
1 | Properties props = new Properties(); |