Optional은 JAVA8 버전 이상 부터 지원해주는 기능이다. 간단하게 NPE을 피하기 위해 사용된다. Optional을 통해 검증하여 코드를 짜면서 스스로 좀 더 Optional을 활용하여 코드를 더 잘 작성하고 싶다는 생각이 들면서 글을 작성해본다.
Optional 대해
Optional 객체를 사용하면 예상치 못한 NullPointerException 예외를 제공되는 메소드로 간단히 회피할 수 있다.
즉, 복잡한 조건문 없이도 널(null) 값으로 인해 발생하는 예외를 처리할 수 있게 된다.get()메소드를 사용하면 Optional 객체에 저장된 값에 접근할 수 있다.
Optional 생성 하는 방법
//Optional 생성하는 방법
String str = "test";
Optional<String> str1 = Optional.of(str);
Optional<Object> o = Optional.of(null); // NullPointerException 발생
Optional<Object> o2 = Optional.ofNullable(null); // NPE 발생하지 않음
Optional 값 가져오기
// Optional 값 가져오기
Optional<String> s = Optional.ofNullable("aa");
String s1 = s.get();
String s3 = s.orElse("다른 other");
String s4 = s.orElseGet(String::new);
String s2 = s.orElseThrow(RuntimeException::new);
// get() : 거의 사용하지 않음 (테스트 할 때나 편하게 하려고 사용할 듯)
// orElse() : Optional 객체 null이면 같은 타입 다른 객체를 반환 할 수 있다.
// orElseGet() : Optinal 객체가 null이면 람다식으로 이용하여 객체를 반환 한다.
orElse() vs orElseGet() 차이
결론은 orElseGet() 을 사용하도록 하자.
public final class Optional<T> {
... // 생략
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
}
orElse()는 파라미터로 해당 객체타입을 그대로 받는다. orElseGet()은 함수형 인터페이스로 받는다 두개의 차이점은 상당히 크다.orElse()는 파라미터로 반환값을 호출한다. 반환값을 호출한다는 뜻은 메소드를 호출하여 return 값을 가진 다음에 이후 객체가 null인지 검증한다는 뜻이다.orElseGet()은 함수 자체를 일단 파라미터로 가져온다. (반환값을 리턴하는 것와 다르다) 말 그대로 함수 자체를 가져올 뿐 아직 실행 전이다.
그 후에 객체 null 검증 → 객체가 null 이면 orElseGet() 파라미터에 선언한 파라미터 실행
요약
orElse()는 반환 값 먼저 받고 객체 검증
orElseGet()는 객체 검증 하고 null이면 반환 값 리턴
orElse()는 orElseGet() 보다 비용이 더 비쌈
Optinal을 잘 사용하기 위해서는 어떻게 해야할까?
Optional을 사용하므로써 null-safe한 코드를 깔끔하게 만들 수 있다는 장점이 있다. 그렇다면 무조건 Optional을 사용하는 것이 옳을까? 그렇지 않다고 생각한다.
Optional을 떠나 모든 기술에 대해서 필요할 경우에 적재적소에 맞게 사용 하는 것이 항상 옳다라고 생각한다. Optional을 사용하므로써 발생할 수 있는 문제점에서 대해 먼저 알아보자.
1. 이전에 없던 새로운 문제점이 생김
- 기본적으로 Optional은 직렬화를 지원하지 않기때문에 캐시나 메세지큐를 사용할 때 문제가 생길 수 있다.
2. 코드의 가독성이 안좋아짐
- Optional로 객체를 한번 더 감싸니깐 꺼내올때나 생성할 때 추가 코드 발생
3. 시간적 비용, 공간적 비용이 생김 (오버헤드)
- Optinal을 생성하기 때문에 메모리에 추가 비용 발생
- 값을 꺼내올때 접근 비용 발생
올바른 Optional 사용법 가이드
Optional 변수에 Null을 할당하지 말아라
Optional 안에 null 선언 하는것 보다 Optional.empty() 을 사용하여 초기화 하자.
값이 없을 때 Optional.orElseX()로 기본 값을 반환하라
isPresent()로 검사하고 get()으로 값을 꺼내기 보다는 orElseGet() 등을 활용해 처리하도록 하자.
단순히 값을 얻으려는 목적으로만 Optional을 사용하지 마라
코드 가독성 ↓ 비용 문제 ↑
생성자, 수정자, 메소드 파라미터 등으로 Optional을 넘기지 마라
Optional은 반환 타입으로 대체 동작을 사용하기 위해 고안된다는 것을 명심 해야 할 것.
Collection의 경우 Optional이 아닌 빈 Collection을 사용하라
코드 가독성 ↓ 비용 문제 ↑
반환 타입으로만 사용하라
Optional 자주 사용할 것 같은 메소드 정리
| 메소드 | 설명 |
| isPresent() | Optional 안에 값이 존재한다면 true |
| isEmpty() | Optional 안에 값이 존재하지 않는다면 true |
| ifPresent(Consumer<? super T> consumer) | 값이 존재한다면 특정 동작 실행 |
| ifPresentorElse(Consumer<? super T> action, Runnable emptyAction) | 값이 존재하면 첫번째 파라미터 action 동작 수행 그렇지 않다면 두번째 파라미터 emptyAction 동작 수행 |
참고자료
[Java] 언제 Optional을 사용해야 하는가? 올바른 Optional 사용법 가이드 - (2/2)
[Java] 언제 Optional을 사용해야 하는가? 올바른 Optional 사용법 가이드 - (2/2)
앞선 포스팅에서는 Optional의 개념과 문법을 살펴보았습니다. Optional은 Null이 될 수 있는 객체를 감싸는 Wrapper 클래스이기 때문에 비용이 발생합니다. 그래서 Optional은 필요한 경우에만 사용하는
mangkyu.tistory.com
자바 옵셔널 (Java Optional) :: JDM's Blog
개요 자바 옵셔널Java Optional에 대해 알아보고 자바 8부터 시작해 9, 10까지 추가된 옵셔널 메서드를 소개합니다. Java 8 Optional 자바 옵셔널은 자바 8에서 최초로 도입 되었습니다. 도입이 된 이유는
jdm.kr
'JAVA' 카테고리의 다른 글
| Java8 : Stream 사용법 (0) | 2023.03.31 |
|---|---|
| sigton Patten이란? (0) | 2023.03.31 |
| Garbeage Collection 이란? (0) | 2023.03.31 |
| JAVA 동작원리 그리고 JVM (0) | 2023.03.30 |
| Comparable 과 Comparator 차이점 (0) | 2023.03.30 |