티스토리 뷰
✅ 이 글은 Optional을 잘 알고 있는 사람에게는 어울리지 않는 글입니다. 헷갈림을 유발할 수 있습니다.
오늘 Java의 Optional에 대해서 알게 된 점을 쓴다. 제목에 부끄럽지만을 썼지만 뺐다. Java8부터 나온 Optional 이 몇 년이나 지났지만 알고 있다고 사용한 부분에서 전혀 다른 결과가 나와서 순간 뭐지? 했다가 아차 싶어서 쓰는 글이다. 예제로 살펴본다.
Optional 이란?
Java8에서는 Optional<T> 클래스를 사용해 NPE를 방지할 수 있도록 도와준다. Optional<T>는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다. Optional 클래스는 아래와 같은 value에 값을 저장하기 때문에 값이 null이더라도 바로 NPE가 발생하지 않으며, 클래스이기 때문에 각종 메서드를 제공해 준다.
public final class Optional<T> {
// If non-null, the value; if null, indicates no value is present
private final T value;
...
}
진짜 Optional의 방식
억지스러운 예제라도 생각나는 게 이런 거밖에 없다.
@Test
@DisplayName("Optional ofNullable")
void optionalNullableTest() throws Exception {
//given
String value = "example";
//when
final String result = Optional.ofNullable(value)
.map(String::toUpperCase)
.orElseGet(() -> "Default value");
//then
assertThat(result).isEqualTo("EXAMPLE");
}
null 이 올 수 있는 값을 Optional로 감싸서 NPE가 발생하지 않도록 도와주고 null일 경우 default 값을 설정해 줄 수 있는 코드이다.
@Test
@DisplayName("Optional ofNullable")
void optionalNullableTest() throws Exception {
//given
String value = "example";
//when
final String result = Optional.ofNullable(value)
.map(v -> {
if("example".equals(v)) {
return null;
}
return v.toUpperCase();
})
.orElseGet(() -> "Default Value");
//then
assertThat(result).isEqualTo("Default Value");
}
- 이 코드에서 map은 Optional 내부에 값이 있으면 해당 값을 대문자로 변환하는 함수 v -> v.toUpperCase()를 실행한다.
- 그러나 map 내부 함수는 value가 "example"일 때 null을 반환한다.
- Optional은 map 결과가 null일 때 empty 상태가 되므로 orElseGet 부분이 실행되어 "Default value"를 반환하게된다.
value 값만을 생각해서 Optional을 if-else 개념으로 생각했었던 것 같다. 지금은 확실히 알았음.
틀린생각
외부에서 들어오거나 평가되는 값이 null이면 중간연산만 실행아니면 orElseGet()
map 에서 null이 리턴되거나 exception이 발생하면 그대로 null값으로 들어가는 걸로 생각 했는데 그게아니라 map의 결과가 null 이므로 empty 상태가 되기때문에 orElseGet 부분이 실행되는 부분이었다 ㅜㅜ_ㅜㅜ
지금은 이제 완벽히 알게돼서 안적을 까 하다가 무엇이든 남겨놓자는 생각으로 적어봤다.
참고
https://mangkyu.tistory.com/70
https://www.daleseo.com/java8-optional-effective/
- Total
- Today
- Yesterday
- LocalDateTime
- LocalDate
- Spring Security
- Github Status
- window
- intellij
- JavaScript
- config-location
- 베리 심플
- oracle
- svn
- elasticsearch
- Bash tab
- Kotlin
- maven
- Mac
- 오라클
- springboot
- mybatis config
- rocky
- mybatis
- jQuery
- Java
- Spring
- k8s
- 북리뷰
- input
- docker
- Linux
- localtime
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |