728x90
Java 8에서 도입된 Optional<T>은 null 처리를 안전하게 할 수 있도록 설계된 컨테이너 클래스입니다. null 값 처리 문제를 보다 안전하고 간결한 방식으로 해결할 수 있습니다.
1. Optional 객체 생성 방법
1.1. Optional.of(T value)
null이 아닌 값을 포함하는 Optional 객체를 생성합니다.
Optional<String> opt = Optional.of("Hello");
System.out.println(opt.get()); // Hello
1.2. Optional.ofNullable(T value)
값이 null일 수도 있을 경우 사용합니다.
Optional<String> opt = Optional.ofNullable(null); // 빈 Optional 반환
System.out.println(opt.isPresent()); // false
1.3. Optional.empty()
빈 Optional 객체를 생성합니다.
Optional<String> opt = Optional.empty();
System.out.println(opt.isPresent()); // false
2. Optional 값 처리 방법
2.1. isPresent() - 값이 존재하는지 확인
Optional<String> opt = Optional.of("Hello");
if (opt.isPresent()) {
System.out.println(opt.get()); // Hello
}
2.2. ifPresent(Consumer<? super T> consumer) - 값이 있을 때 실행
Optional<String> opt = Optional.of("Hello");
opt.ifPresent(value -> System.out.println("Value: " + value)); // Value: Hello
2.3. orElse(T other) - 기본값 설정
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse("Default Value")); // Default Value
2.4. orElseGet(Supplier<? extends T> supplier) - 기본값을 제공하는 함수 사용
Optional<String> opt = Optional.empty();
System.out.println(opt.orElseGet(() -> "Computed Default Value")); // Computed Default Value
2.5. orElseThrow(Supplier<? extends Throwable> exceptionSupplier) - 예외 던지기
Optional<String> opt = Optional.empty();
String value = opt.orElseThrow(() -> new IllegalStateException("Value not found"));
3. Optional 변환 및 필터링
3.1. map(Function<? super T, ? extends U> mapper) - 값 변환
Optional<String> opt = Optional.of("Hello");
Optional<Integer> lengthOpt = opt.map(String::length);
System.out.println(lengthOpt.orElse(0)); // 5
3.2. flatMap(Function<? super T, ? extends Optional<U>> mapper) - 중첩 Optional 해제
Optional<String> opt = Optional.of("Hello");
Optional<Integer> flatMapped = opt.flatMap(str -> Optional.of(str.length()));
System.out.println(flatMapped); // Optional[5]
3.3. filter(Predicate<? super T> predicate) - 조건 필터링
Optional<String> opt = Optional.of("Hello");
Optional<String> filteredOpt = opt.filter(s -> s.startsWith("H"));
System.out.println(filteredOpt.orElse("No match")); // Hello
4. Optional 활용 예제
4.1. 기존 방식 vs Optional을 활용한 방식
기존 null 체크 방식
public String getUserName(User user) {
if (user != null) {
Profile profile = user.getProfile();
if (profile != null) {
return profile.getName();
}
}
return "Unknown";
}
Optional을 활용한 방식
public String getUserName(User user) {
return Optional.ofNullable(user)
.map(User::getProfile)
.map(Profile::getName)
.orElse("Unknown");
}
5. 주의사항
- Optional<T>은 필드로 사용하지 말 것: Optional은 리턴 타입으로만 사용해야 하며, 필드나 매개변수로 사용하면 불필요한 객체 생성이 발생할 수 있습니다.
- 성능 고려: Optional은 null 체크를 간편하게 해주지만, 불필요하게 사용하면 객체 생성 비용이 발생할 수 있습니다.
6. 결론
- Optional<T>은 null을 안전하게 처리할 수 있도록 도와주는 클래스.
- orElse(), orElseGet(), orElseThrow() 등을 활용하여 기본값 처리 가능.
- map(), flatMap(), filter() 를 사용하여 값 변환 및 필터링 가능.
- 무분별한 사용을 지양하고, 리턴 타입으로 활용하는 것이 가장 적절함.
➡ Optional을 올바르게 활용하면 코드가 간결해지고 NullPointerException을 방지할 수 있음!
728x90
'개발 > 자바' 카테고리의 다른 글
| UUID v7: 시간 기반의 차세대 UUID (0) | 2025.02.10 |
|---|---|
| Java UUID란? (0) | 2025.02.08 |
| Java의 private, private static, private static final 차이점 (0) | 2025.01.29 |
| Java 1.7과 Java 1.8의 주요 변경 사항 비교 정리 (1) | 2025.01.21 |
| 전자정부프레임워크 4.x(spring boot) 외부 톰캣에서 실행하기 (0) | 2025.01.15 |