Java Optional<T> 사용법 완벽 이해하기
Java 개발에서 가장 흔하고 위험한 예외 중 하나가 바로:
NullPointerException (NPE)
입니다.
실무에서는 정말 수도 없이 발생합니다.
예:
user.getAddress().getCity()
에서:
- user가 null
- address가 null
이면 바로 NPE 발생.
이 문제를 해결하기 위해 Java 8에서 등장한 것이 바로:
Optional<T>
입니다.
하지만 많은 개발자가 Optional을:
null 대신 쓰는 박스 객체?
정도로만 이해합니다.
실제로 Optional은:
- 함수형 프로그래밍
- Null 안전성
- Stream API
- map/flatMap
- Lazy Evaluation
까지 연결되는 중요한 개념입니다.
이번 글에서는:
- Optional이란?
- 왜 등장했는가
- of / ofNullable / empty
- map / flatMap
- orElse / orElseGet 차이
- Optional 남용 문제
- 실무 사용 전략
까지 깊게 정리해보겠습니다.
1. Optional<T>란?
Optional 은:
값이 존재할 수도 있고 없을 수도 있음을 표현하는 객체
입니다.
2. 왜 필요할까?
기존 Java는:
값 없음 = null
표현.
문제는:
null 체크 누락
↓
NPE 발생
이 매우 흔함.
3. 기존 방식 문제
예:
User user = findUser();
if (user != null) {
System.out.println(user.getName());
}
4. 문제점
실무에서는:
null 체크 반복 지옥
발생.
5. Optional 등장
목표:
“값이 없을 수도 있음”
을 타입 시스템으로 표현.
6. 가장 기본 생성 방법
Optional<String> opt =
Optional.of("Java");
7. 의미
값 존재 보장
입니다.
8. 주의점
Optional.of(null)
↓
NullPointerException
발생.
9. null 가능 시 사용
Optional.ofNullable(value)
10. 예시
Optional<String> opt =
Optional.ofNullable(name);
11. null이면?
Optional.empty()
생성.
12. 빈 Optional
Optional.empty()
↓
값 없음 표현
입니다.
13. 값 꺼내기
대표 메서드:
get()
14. 예시
String s = opt.get();
15. 그런데 매우 위험
값 없으면:
NoSuchElementException
발생.
16. 실무에서 get() 지양
매우 중요.
보통:
Optional 의미 사라짐
가능.
17. 안전한 방법: isPresent()
if (opt.isPresent()) {
System.out.println(opt.get());
}
18. 하지만 이것도 문제
사실상:
null 체크와 비슷
해짐.
19. 더 좋은 방식: ifPresent()
opt.ifPresent(System.out::println);
20. 의미
값 존재 시만 실행
입니다.
21. orElse()
매우 중요.
22. 예시
String name =
opt.orElse("default");
23. 의미
값 없으면 기본값 사용
입니다.
24. 그런데 중요한 문제
매우 중요.
orElse(...)
는:
항상 인자 계산
합니다.
25. 예시
opt.orElse(createValue())
26. 값이 이미 있어도?
createValue()
실행됨.
27. 그래서 등장한 orElseGet()
opt.orElseGet(() -> createValue())
28. 차이
필요할 때만 실행
즉:
Lazy Evaluation
지원.
29. 실무에서 매우 중요
무거운 객체 생성 시:
orElseGet()
더 적절.
30. orElseThrow()
예외 처리용.
31. 예시
User user =
opt.orElseThrow(
() -> new RuntimeException()
);
32. map()
Optional 핵심 메서드.
33. 의미
값 변환(transform)
입니다.
34. 예시
Optional<String> upper =
opt.map(String::toUpperCase);
35. 내부적으로 Function 사용
즉:
입력 → 출력 변환
수행.
36. 값 없으면?
매우 중요.
map 자체 실행 안 함
즉 empty 유지.
37. Optional Chain 가능
예:
Optional.of(user)
.map(User::getAddress)
.map(Address::getCity)
38. 장점
중간 null 안전 처리
가능.
39. flatMap()
매우 중요.
많이 헷갈림.
40. 문제 상황
Optional<Optional<String>>
같은 중첩 발생 가능.
41. flatMap 역할
중첩 Optional 평탄화(flatten)
합니다.
42. 예시
opt.flatMap(User::getNameOptional)
43. map vs flatMap 차이
| map | Optional<Optional<T>> 가능 |
| flatMap | Optional<T> |
44. filter()
Optional에도 존재.
45. 예시
opt.filter(name -> name.length() > 3)
46. 의미
조건 불만족 시:
empty 반환
입니다.
47. Stream과 Optional 연결
대표:
findFirst()
findAny()
max()
min()
등은 Optional 반환.
48. 왜 Optional 반환할까?
값 없을 가능성 때문.
49. Optional의 철학
매우 중요.
“null 가능성을 명시적으로 표현”
입니다.
50. 그런데 Optional 남용 문제 존재
실무에서 매우 중요.
51. 안 좋은 예 1
필드에 Optional 사용.
class User {
Optional<String> name;
}
52. 왜 문제일까?
Optional은 원래:
반환 타입 용도
에 더 적합.
53. 안 좋은 예 2
메서드 파라미터 Optional.
save(Optional<User> user)
보통 비추천.
54. 안 좋은 예 3
Optional.get() 남발.
null 체크와 차이 사라짐
55. Optional 성능 이슈?
일반적으로 큰 문제는 아니지만:
객체 생성 비용
존재.
특히 primitive는:
OptionalInt
OptionalLong
등 사용 가능.
56. 실무 권장 패턴
매우 중요.
| 반환값 nullable | Optional 반환 |
| 필드 | 보통 Optional 지양 |
| 파라미터 | Optional 지양 |
| Stream 결과 | Optional 적극 사용 |
57. Optional vs null
| 의미 명시 | X | O |
| 타입 안정성 | 낮음 | 높음 |
| NPE 위험 | 높음 | 감소 |
| 함수형 처리 | 어려움 | 쉬움 |
58. 핵심 흐름 요약
값 존재 가능
↓
Optional 래핑
↓
map/filter/flatMap 체인
↓
orElse/orElseGet 처리
59. 가장 중요한 핵심 한 줄
Optional은
“값이 없을 가능성을 타입으로 표현하는 컨테이너”
입니다.
60. 정리
Optional은 단순 null 대체 객체가 아닙니다.
실제로는:
- 함수형 프로그래밍
- Stream API
- Null 안전성
- map/flatMap
- Lazy Evaluation
전체와 연결되는 Java 8 이후 핵심 기능입니다.
특히 실무에서는:
- of / ofNullable 차이
- orElse vs orElseGet
- map / flatMap
- Optional 남용 방지
- 반환 타입 설계
를 정확히 이해하는 것이 매우 중요합니다.
다음 글에서는:
Optional 남용 문제
를 Optional 필드 사용 금지 이유, JPA 충돌, 성능 문제, 실무 설계 전략까지 포함해서 깊게 정리해보겠습니다.
'language > java' 카테고리의 다른 글
| Java 함수형 프로그래밍 패러다임 이해 완벽 정리 (0) | 2026.05.28 |
|---|---|
| Java Optional 남용 문제 완벽 이해하기 (0) | 2026.05.28 |
| Java Collector 활용 완벽 이해하기 (0) | 2026.05.28 |
| Java Method Reference(::) 완벽 이해하기 (0) | 2026.05.28 |
| Java Stream API 기초 완벽 이해하기 (0) | 2026.05.27 |
댓글