반응형
☕️ Optional이란?
Optional은 NULL이 올 수 있는 값을 감싸는 Wrapper 클래스로, Java 8에서 추가되었으며 NULL을 보다 편리하게 핸들링하여 NPE을 발생하지 않도록 도와준다.
☕️ Optional 생성
Optional은 아래와 같은 방법으로 생성할 수 있다.
- Optional.of(T value)
- value를 Optional로 감싼 객체를 생성한다. 이때 주의할 점은 만약 value가 null이라면 NPE가 발생한다. - Optional.ofNullable(T value)
- value를 Optional로 감싼 객체를 생성한다. Optional.of()와의 차이점은 value가 null이라도 NPE가 발생하지 않는다. - Optional.empty()
- 빈 객체를 생성한다.
import java.util.Optional;
public class OptionalEx {
public static void main(String[] args) {
/** 1. Optional.of() */
Optional<String> opt1 = Optional.of("aaa");
System.out.println(opt1); // Optional[aaa]
System.out.println(opt1.get()); // aaa
// Optional<String> opt2 = Optional.of(null); // NPE 발생
/** 2. Optional.ofNullable() */
Optional<String> opt3 = Optional.ofNullable(null); // NPE이 발생하지 않는다.
System.out.println(opt3); // Optional.empty
// System.out.println(opt3.get()); // NoSuchElementException 발생
/** 3. Optional.empty() */
// Optional<String> nullOpt1 = null;
Optional<String> nullOpt2 = Optional.empty(); // 초기화 값을 지정하지 않고 초기화할 경우, null 대신 Optional.empty() 권장
}
}
반응형
☕️ Optional로 NULL 판단
Optional은 아래의 메서드를 사용하여 NULL여부를 판단할 수 있다.
- Optional.isPresent()
- 값이 있다면 TRUE를 반환하고, 값이 없다면 FALSE를 반환한다. - Optional.isEmpty()
- isPresent()와 반대로 값이 없다면 TRUE를 반환하고, 값이 있다면 FALSE를 반환한다.
import java.util.Optional;
public class OptionalEx {
public static void main(String[] args) {
Optional<String> optNull1 = Optional.ofNullable("ABC");
System.out.println(optNull1.isPresent()); // true
System.out.println(optNull1.isEmpty()); // false
Optional<String> optNull2 = Optional.ofNullable(null);
System.out.println(optNull2.isPresent()); // false
System.out.println(optNull2.isEmpty()); // true
}
}
☕️ Optional로 값 가져오기
Optional은 아래의 메서드를 사용하여 값을 가져올 수 있다.
- Optional.get()
- Optional 안의 값을 가져온다. 단, 값이 NULL이면 NoSuchElementException이 발생한다. - Optional.orElse(T other)
- Optional 안의 값을 가져온다. 만약 값이 NULL이라면 other값으로 대체한다. - Optional.orElseGet(Supplier<? extends T> supplier)
- Optional 안의 값을 가져온다. 만약 값이 NULL이라면 함수형 인터페이스를 수행한 결과로 대체한다.
import java.util.Optional;
public class OptionalEx {
public static void main(String[] args) {
String nullStr = null;
String notNullStr = "ABC";
// System.out.println(Optional.ofNullable(nullStr).get()); // NoSuchElementException 발생
System.out.println(Optional.ofNullable(notNullStr).get()); // ABC
System.out.println(Optional.ofNullable(nullStr).orElse("XYZ")); // XYZ
System.out.println(Optional.ofNullable(notNullStr).orElse("XYZ")); // ABC
System.out.println(Optional.ofNullable(nullStr).orElseGet(() -> "XYZ")); // XYZ
System.out.println(Optional.ofNullable(notNullStr).orElseGet(() -> "XYZ")); // ABC
}
}
☕️ Optional.orElse()과 Optional.orElseGet()의 차이
orElse()과 orElseGet() 메서드 모두 값이 NULL일 때 방어코드 용도로 사용할 수 있는 메서드이다.
하지만 두 개의 메서드에는 큰 차이점이 있다. orElse()는 null값 여부와 상관없이 항상 호출되고, orElseGet()는 null일 때만 호출된다.
따라서 두 개의 메서드를 제대로 알고 사용하지 않는다면 수행결과에 있어서 다른 결과를 초래할 수 있게 될 수 있으니 주의하자.
import java.util.Optional;
public class OptionalEx {
public static void main(String[] args) {
String nullStr = "ABC";
String notNullStr = null;
System.out.println(Optional.ofNullable(nullStr).orElse(getDefaultValue()));
/* - 실행결과
* # getDefaultValue() 실행
* default
*/
System.out.println(Optional.ofNullable(notNullStr).orElse(getDefaultValue()));
/* - 실행결과 (NULL이 아닌데도 getDefaultValue()가 수행된다.)
* # getDefaultValue() 실행
* ABC
*/
System.out.println(Optional.ofNullable(nullStr).orElseGet(OptionalEx::getDefaultValue));
/* - 실행결과
* # getDefaultValue() 실행
* default
*/
System.out.println(Optional.ofNullable(notNullStr).orElseGet(OptionalEx::getDefaultValue));
/* - 실행결과 (NULL이 아니어서 getDefaultValue()가 수행되지 않았다.)
* ABC
*/
}
static String getDefaultValue() {
System.out.println("# getDefaultValue() 실행");
return "default";
}
}
☕️ Optional로 예외 발생시키기
Optional은 아래의 메서드를 사용하여 예외를 발생시킬 수 있다.
- Optional.orElseThrow(Supplier<? extends X> exceptionSupplier)
- Optional 안의 값이 NULL이라면 예외를 발생시킨다.
import java.util.Optional;
public class OptionalEx {
public static void main(String[] args) {
String userName = "CHOI";
String userNullName = null;
System.out.println(Optional.ofNullable(userName).orElseThrow(IllegalArgumentException::new)); // CHOI
System.out.println(Optional.ofNullable(userNullName).orElseThrow(IllegalArgumentException::new)); // IllegalArgumentException 발생
}
}
orElseThrow() 메서드를 적절하게 사용한다면 코드의 가독성을 높일 수 있다는 장점이 있다.
JPA에서 상품을 조회하는 로직을 통해 그 예시를 알아보자.
public class ItemService {
Item findItemById(Long itemId) {
Optional<Item> item = itemRepository.findById(itemId);
if(item.isEmpty()) {
throw new NoSuchElementException();
}
return item.get();
}
// orElseThrow를 사용하여 가독성 높이기
Item findItemById_orElseThrow(Long itemId) {
return itemRepository.findById(itemId)
.orElseThrow(() -> new NoSuchElementException());
}
}
References.
1. 망나니개발자 - [Java] Optional이란? Optional 개념 및 사용법 - (1/2)
2. highright96 - java.util.Optional이란?
반응형
'IT' 카테고리의 다른 글
[Java] Checked Exception과 Unchecked Exception (3) | 2025.01.22 |
---|---|
[Java] java.time 패키지 (2) | 2025.01.22 |
[Java] 스트림 API(Stream API) (1) | 2025.01.22 |
[Java] 진법 변환(10진수 <-> N진수) (1) | 2025.01.22 |
[Java] 메서드 참조(Method Reference) (1) | 2025.01.22 |