홈 › 고급 › 05 / 10

Optional로 NPE 방지

섹션 7진행 0 / 10

Optional — "없을 수 있음"을 타입으로 표현하기

null 이 왜 위험한지, Optional 이 무엇을 해결하고 무엇을 해결하지 않는지, orElse 와 orElseGet 의 평가 시점 차이, map/flatMap 체인, 안티패턴을 이해하고, Repository 조회·설정 fallback·중첩 DTO 접근을 NPE 없이 작성할 수 있게 됩니다.

1. 왜 배우는가

운영 장애 로그에서 가장 많이 보이는 예외는 NullPointerException 입니다.

user.getAddress().getCity().toUpperCase() 에서 어느 하나가 null 이면 터지고, 스택 트레이스는 "한 줄"만 가리키므로 셋 중 무엇이 null 이었는지 알려면 디버거를 붙여야 합니다(JDK 14+ 의 helpful NPE 메시지가 많이 개선했지만).

방어하려고 if (x != null) 을 도배하면 로직이 묻히고, 빼먹은 한 곳에서 다시 터집니다.

Optional 은 "이 메서드는 값을 못 돌려줄 수도 있다"를 반환 타입에 명시하는 도구입니다. User findById(id) 는 null 을 줄 수도 있다는 걸 문서를 읽어야 알지만, Optional<User> findById(id) 는 시그니처 자체가 "없을 수 있으니 처리해라"라고 강제합니다.

스프링 데이터 JPA 의 findById, 스트림의 findFirst/max/min/reduce, Files.lines 후처리 등 JDK 8 이후 API 가 전부 Optional 을 돌려주므로 정확히 쓰는 법은 필수입니다.

동시에 Optional 은 남용하기 쉬운 도구입니다. 필드에 넣고, 파라미터로 받고, isPresent() 체크 후 get() 하는 코드는 null 과 다를 게 없으면서 객체 하나를 더 만듭니다. 이 레슨은 설계 의도(Brian Goetz 의 "반환 타입 전용")를 근거로 언제 쓰고 언제 쓰지 말아야 하는지를 분명히 합니다.