[Java] Java Optional
by Roel Downey자바 옵셔널은 자바 8부터 시작되었다. 공식 API 문서: 링크
왜 만들었을까?
공식 API 문서를 들어가면 나와있다.
메서드가 반환할 결과값이 없음을 명백하게 표현할 필요가 있고, 널을 반환하면 에러를 유발할 가능성이 높은 상황에서 메서드의 반환 타입으로 옵셔널을 사용하자는것이다. 옵셔널 타입의 변수의 값은 절대 널 이어서는 안되며, 항상 옵셔널 인스턴스를 가리켜야 한다.
java.util.Optional<T> 클래스
Optional<T> 클래스는 Integer나 Double 클래스처럼 'T'타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)이다.
따라서 Optional 인스턴스는 모든 타입의 참조 변수를 저장할 수 있다.
이러한 Optional 객체를 사용하면 예상치 못한 NullPointerException 예외를 제공되는 메소드로 간단히 회피할 수 있다.
즉, 복잡한 조건문 없이도 널(null) 값으로 인해 발생하는 예외를 처리할 수 있게 된다.
Optional 객체 생성
Optional 객체를 생성하기 위해서는 Optional.of 와 Optional.ofNullable, Optional.empty 3가지를 사용한다.
Optional을 필드로 사용하지 말자.
Optional<String> optString = Optional.of("Hello");
value가 null 인 경우 java.lang.NullPointerException 이 발생한다.
Optional<String> optString = Optional.ofNullable(null);
value가 null 인 경우 비어있는 Optional 반환한다.
Optional<String> emptyOpt = Optional.empty();
비어있는 Optional 객체를 생성한다.
Optional 처리
Optional 처리를 하기 위해 filter, map, flatMap 이 있다.
Optional.of("True").filter((val) -> "True".eqauls(val)).orElse("NO DATA"); // "True"
Optional.of("False").filter(
(val) -> "True".eqauls(val)
).orElse("NO DATA"); // "NO DATA"
filter( ) 안에 값이 참이면 해당 필터를 통과 시키고 거짓이면 통과 시키지 않는다.
Integer intValue = Optional.of("1").map(Integer::valueOf).orElseThrow(NoSuchElementException::new); // string to integer
mapper 함수를 통해 입력값을 다른 값으로 변환하는 메서드 이다.
String result = Optional.of("result")
.flatMap((val) -> Optional.of("good"))
.get();
System.out.println(result); // print 'good'
mapper 함수를 통해 입력값을 다른 값으로 변환하는 메서드 이다.
map() 과 flatMap 다른점은 메서드 시그니처의 매개변수 이다.
map() 은 제네릭으로 정의한다. flatMap 은 Optional 제네릭으로 정의한다.
flatMap() 메서드가 반환해야 하는 값은 Optional 이다.
Optional 마무리
ifPresent, isPresent, get, orElse, orElseGet, orElseThrow
// 예제 1
Optional.of("test").ifPresent((value) -> {
// something to do
});
// 예제2 (ifPresent 미수행)
Optional.ofNullable(null).ifPresent((value) -> {
// nothing to do
});
최종적으로 연산을 끝낸 후 값이 비어있지 않다면 입력값으로 주어지고, 비어 있다면 메서드의 내용이 수행되지 않는다.
Optional.ofNullable("test").isPresent(); // true
Optional.ofNullable("test").filter((val) -> "result".eqauls(val)).isPresent(); // false
최종적으로 연산을 끝낸 후 객체가 존재하는지 여부를 판별
Optional.of("test").get(); // 'test'
Optional.ofNullable(null).get(); // NoSuchElementException!
객체를 꺼낸다. 비어있다면 예외가 발생한다.
String result = Optional.ofNullable(null).orElse("default");
System.out.println(result); // print 'default'
연산을 끝낸 후에 Optional로 객체가 비어있다면 기본값으로 제공할 객체를 지정한다.
Optional 객체가 비어있던 비어있지 않던 반드시 실행한다.
String result = Optional.ofNullable("input").filter("test"::equals).orElseGet(() -> "default");
System.out.println(result); // print 'default'
연산을 끝낸 후에 Optional로 객체가 비어있다면 기본값으로 제공할 함수를 지정한다.
Optional 객체가 비어있으면 실행한다. 새로운 객체 생성이나 새로운 연산을 수행하는 경우 사용한다.
Optional.ofNullable("input").filter("test"::equals).orElseThrow(NoSuchElementException::new);
연산 끝낸 후 Optional 객체가 비어있다면 예외 공급자 함수를 통해 예외를 발생시킨다.
'Java' 카테고리의 다른 글
[Java] 1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. (0) | 2020.11.16 |
---|---|
[디자인패턴] 빌더 패턴 (Builder) (0) | 2020.08.30 |
[Java] statement와 PreparedStatement (1) | 2020.05.13 |
[Java] JUnit4 사용하기 (Eclipse에서) (0) | 2020.04.06 |
[Java] 추상 클래스(abstract Class) (0) | 2020.03.20 |
블로그의 정보
What doing?
Roel Downey