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(); |
