생성
Optional<String> opt1 = Optional.of("Hello"); // 값이 절대 NULL이 아니어야함
Optional<String> opt2 = Optional.ofNullable(null); // NULL 허용
Optional<String> opt3 = Optiona.empty(); // 비어있는 Optional
값 조회
opt1.get(); // 값 가져오기(값이 없으면 NoSuchElementException 발생)
opt1.orElse("Default"); // 값이 없으면 기본값 리턴
opt1.orElseGet(() -> "Default"); // Supplier 사용
opt1.orElseThrow(); // 값 없으면 예외 발생(기본 예외)
opt1.orElseThrow(() -> new IllegalArgumentException("No value")); // 값 없으면사용자 정의 예외
값 검사
opt1.isPresent(); // 값이 있으면 true 반환
opt1.isEmpty(); // Java 11부터 추가, 값이 없으면 true 반환
값 처리
opt1.ifPresent(value -> System.out.println(value)); // 값이 있을 때만 동작
opt1.ifPresentOrElse(
value -> System.out.println("값: " + value);
() -> System.out.println("값 없음");
); // Java 9부터 추가
Optional 체이닝 변환
opt1.map(String::toUpperCase); // 값이 있으면 변환
opt1.flatMap(val -> Optional.of(val.toUpperCase())); // 중첩 Optional 방지
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
Optional<user> optionalUser = findById(id);
User user = optionalUser.getOrElseThrow(() -> new DataNotFoundException("회원을 찾을 수 없습니다"));
| 항목 | 설명 |
|---|---|
| ❌ 필드에 사용 X | 클래스의 필드로 Optional을 선언하지 말 것 (Optional<User> user → User user) |
| 어떤 시점에 존재 여부가 명확하지 않은 값을 안전하게 다루기 위한 도구이지 객체의 상태를 표현하기 위한 용도가 아님 | |
| ❌ 컬렉션 내부에 사용 X | List<Optional<T>>보다 List<T> 자체를 빈 리스트로 처리 |
❌ get() 직접 호출 자제 |
예외 발생 가능성 높음, orElse, orElseThrow, ifPresent 사용 권장 |
| ❌ Serializable이 아님 | 직렬화가 필요한 경우 주의(JSON, JPA, 캐시 등을 사용하려고 하면 예외가 발생하거나 예상치 못한 동작 가능성 주의) |
null일 수 있는 메서드에서 명시적으로 값의 존재 여부를 표현하고 싶을 때NPE(Null Pointer Exception)을 방지하고 싶을 때