➡️Optional이란?
- Java8에서 Optional<T>클래스를 사용해 NPE(NullPointException)을 방지할 수 있도록 도와준다.Optional<T>는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다. Optional 클래스는 value에 값을 저장하기 때문에 value가 null이어도 NPE를 발생시키기 않는다.
➡️NPE(NullPointException)
우리가 개발을 할때 가장 많이 발생하고 힘들게하는 예외 중 하나가 NPE(NullPointException)이다. NPE(NullPointException)를 발생시키지 않을려면 null을 검증하는 로직을 추가 해야 하는데 , null을 검증해야하는 변수가 많으면 많을수록 코드가 지저분해지고 로직이 번거로워진다.그래서 null대신 초기값을 사용하기를 권장하기도 한다.
➡️Optional 객체 생성
>Optional.of : value가 null인 경우 NPE예외를 던진다. 반드시 값이 있어야 하는 객체인 경우 해당 메서드를 사용하면 된다.
>Optional.ofNullable : value가 null 인 경우 비어있는 Optional을 반환한다. 값이 null일수도 있는 것은 해당 메서드를 사용하면 된다.
>Optional.empty : 비어있는 Optional객체를 생성한다. 조건에 따라 분기를 태워야하고 반환할 값이 없는 경우에도 사용된다.
➡️Optional 중간처리
:Optional 객체를 생성 한 후 사용가능한 메서드이다. 해당 메서드들은 다시 옵셔널을 반환하므로 메서드 체이닝을 통해 원하는 로직을 반복 삽입할 수 있습니다.
>filter
:predicate(반환값) 값이 참이면 해당 필터를 통과시키고 거짓이면 통과를 하지 못한다.
1
2
3
4
5
6
|
// 메서드 시그니처
public Optional<T> filter(Predicate<? super T> predicate);
// 예제
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"
|
cs |
>map
: mapper 함수를 통해 입력값을 다른 값으로 변환하는 메서드이다.
1
2
3
|
public<U> Optional<U> map(Function<? super T, ? extends U> mapper);
// 예제
Integer test = Optional.of("1").map(Integer::valueOf).orElseThrow(NoSuchElementException::new); // string to integer
|
cs |
>flatMap
:mapper 함수를 통해 입력값을 다른 값으로 변환하는 메서드이다. map()메서드와 다른점은 메서드 시그니처의 매개변수입니다.
1
2
3
4
5
6
7
|
// 메서드 시그니처
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper);
// 예제
String result = Optional.of("result")
.flatMap((val) -> Optional.of("good"))
.get();
System.out.println(result); // print 'good'
|
cs |
➡️Optional 종단처리
>.ifPresent
: 최종적으로 연산을 끝낸 후 값이 비어있지 않다면 입력값으로 주어진다. 이 값을 가지고 원하는 작업을 수행하면 된다. 하지만 중간 연산을 하다 비어있는 옵셔널 객체를 받게 되면 .ifPresent() 메서드의 내용을 수행하지 않는다.
1
2
3
4
5
6
7
8
9
10
|
// 메서드 시그니처
public void ifPresent(Consumer< ? super T>; consumer);
// 예제1
Optional.of("test").ifPresent((value) ->; {
// something to do
});
// 예제2 (ifPresent 미수행)
Optional.ofNullable(null).ifPresent((value) ->; {
// nothing to do
});
|
cs |
>.isPresent
: 최종적으로 연산을 끝낸 후 객체가 존재하는지 여부를 판별한다.
1
2
3
4
5
|
// 메서드 시그니처
public boolean isPresent();
// 예제
Optional.ofNullable("test").isPresent(); // true
Optional.ofNullable("test").filter((val) ->; "result".eqauls(val)).isPresent(); // false
|
cs |
>.get
: 최종적으로 연산을 끝낸 후 객체가 존재하는지 여부를 판별한다. 없으면 예외를 던진다.
1
2
3
4
5
|
// 메서드 시그니처
public T get();
// 예제
Optional.of("test").get(); // 'test'
Optional.ofNullable(null).get(); // NoSuchElementException
|
cs |
>.orElse
: 최종적으로 연산을 끝낸 후에도 Optional객체가 비어있다면 기본값으로 제공할 객체를 지정한다.
1
2
3
4
5
|
/ 메서드 시그니처
public T orElse(T other);
// 예제
String result = Optional.ofNullable(null).orElse("default");
System.out.println(result); // print 'default'
|
cs |
>.orElseGet
: 최종적으로 연산을 끝낸 후에도 옵셔널 객체가 비어있다면 기본값으로 제공할 공급자 함수를 지정합니다.
1
2
3
4
5
|
// 메서드 시그니처
public T orElseGet(Supplier<? extends T> other);
// 예제
String result = Optional.ofNullable("input").filter("test"::equals).orElseGet(() ->; "default");
System.out.println(result); // print 'default'
|
cs |
>.orElseThrow
: 최종적으로 연산을 끝낸 후에도 Optional객체가 비어있다면 예외 공급자 함수를 통해 예외를 발생시킨다.
1
2
3
4
|
// 메서드 시그니처
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X;
// 예제
Optional.ofNullable("input").filter("test"::equals).orElseThrow(NoSuchElementException::new);
|
cs |
> orElse, orElseGet 중 무엇을 사용할까?
orElse 메서드는 옵셔널 객체가 비어있든 비어있지 않든 반드시 실행 한다. orElseGet 메서드는 옵셔널 객체가 비어있으면 실행합니다. 따라서 기본값을 주고자 할때에 기본값을 구하는 과정이 오래 걸린다면 orElseGet을 사용하는게 좋다.
👉다음에는 JAVA9,JAVA10 에 추가된 메서드를 추가해볼 예정이다.
Reference
'Dev > JAVA' 카테고리의 다른 글
[Code] Refactoring , 리펙토링 (0) | 2022.02.28 |
---|---|
[Design Pattern] 빌더 패턴(Builder Pattern) (0) | 2021.12.02 |
[JAVA]상속(Inheritance) (0) | 2021.06.16 |
[JAVA]삼항연산자(Ternary Operator) (0) | 2021.06.15 |
[JAVA]Primitive type과 Reference type (0) | 2021.04.07 |