[REST API] 5. Optional

문정준's avatar
May 08, 2025
[REST API] 5. Optional

📦 개념 요약

  • Optional<T>null로 인한 예외를 방지하고, 명시적으로 값 유무를 처리할 수 있는 컨테이너 클래스
  • 흔히 null 체크에 사용되던 코드를 더 명확하고 선언적으로 바꾸어줌
  • 비유하자면, "선물 상자에 값이 들어있을 수도, 없을 수도 있다"

🧪 테스트 예제

public class OptionalTest { @Test public void t1() { String name = "metacoding"; Optional<String> opt = Optional.of(name); System.out.println(opt.get()); // metacoding 출력 } @Test public void t1_null() { String name = null; Optional<String> opt = Optional.ofNullable(name); if (opt.isPresent()) { System.out.println(opt.get()); } else { System.out.println("선물박스에 값이 없어요"); } } @Test public void t2() { String name = null; Optional<String> opt = Optional.ofNullable(name); String result = opt.orElseThrow(() -> new RuntimeException("값이 없어요")); System.out.println(result); } @Test public void t3() { String name = null; Optional<String> opt = Optional.ofNullable(name); String result = opt.orElseGet(() -> "metacoding"); // 기본값 리턴 System.out.println(result); // metacoding } }
💡 Optional.of()는 null을 허용하지 않음.
💡 Optional.ofNullable()은 null 허용 (값 없으면 empty).
💡 orElseThrow()는 값 없을 때 예외 발생.
💡 orElseGet()은 값 없을 때 기본값 제공.

🔁 기존 코드 vs Optional 적용

📍 Before: null 체크 수동 처리

public User findById(Integer id) { User user = em.find(User.class, id); if (user == null) { return null; } else { return user; } }

✅ After: Optional 적용

public Optional<User> findById(Integer id) { return Optional.ofNullable(em.find(User.class, id)); }

📌 서비스 계층 적용 예시

❌ Before

User userPS = userRepository.findById(userId); if (userPS == null) throw new Exception404("자원을 찾을 수 없습니다"); userPS.update(updateDTO.getPassword(), updateDTO.getEmail());

✅ After

User userPS = userRepository.findById(userId) .orElseThrow(() -> new Exception404("자원을 찾을 수 없습니다.")); userPS.update(updateDTO.getPassword(), updateDTO.getEmail());

👤 로그인 기능 개선

❌ Before

User user = userRepository.findByUsername(loginDTO.getUsername()); if (user == null) throw new Exception401("유저네임 혹은 비밀번호가 틀렸습니다");

✅ After

User userPS = userRepository.findByUsername(loginDTO.getUsername()) .orElseThrow(() -> new Exception401("유저네임 혹은 비밀번호가 틀렸습니다"));

✅ 유저네임 중복 체크

❌ Before

User user = userRepository.findByUsername(username); Map<String, Object> dto = new HashMap<>(); if (user == null) { dto.put("available", true); } else { dto.put("available", false); }

✅ After

Optional<User> userOP = userRepository.findByUsername(username); Map<String, Object> dto = new HashMap<>(); if (userOP.isPresent()) { dto.put("available", false); } else { dto.put("available", true); } return dto; }

✨ 정리

메서드
설명
Optional.of()
null 허용 ❌ (NPE 발생)
Optional.ofNullable()
null 허용 ⭕
isPresent()
값 존재 여부 확인
orElse()
기본값 제공
orElseGet()
람다식으로 기본값 제공
orElseThrow()
예외 발생
 
Share article

sxias