본문 바로가기
language/java

Java Optional<T> 사용법 완벽 이해하기

by 죄니안죄니 2026. 5. 28.
반응형

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

항목nullOptional
의미 명시 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 충돌, 성능 문제, 실무 설계 전략까지 포함해서 깊게 정리해보겠습니다.

반응형

댓글