Optional
이란?Optional
은 Java 8에 도입된 클래스인데, null을 안전하게 처리하기 위해 사용된다. 기존에는 어떤 메서드가 값을 반환할 때 값이 없으면 null을 반환하는 방식으로 처리했는데, 이 방식은 null을 제대로 처리하지 않으면 NullPointerException
(NPE)이라는 오류가 발생할 수 있다.
Optional
을 사용하면 값이 존재할 수도 있고, 존재하지 않을 수도 있다는 사실을 명확하게 표현할 수 있고, 값을 안전하게 처리할 수 있다.
Optional.ofNullable()
의 역할Optional.ofNullable(value)
는 주어진 값이 null일 수도 있고, 아닐 수도 있을 때 사용.value
가 null이 아니면: 그 값을 가진 Optional
객체를 반환.value
가 null이면: Optional.empty()
를 반환합니다. 즉, 빈 Optional 객체를 반환.String name = null;
// Optional.ofNullable을 사용해 null을 안전하게 처리
Optional<String> optionalName = Optional.ofNullable(name);
// name이 null이므로 Optional.empty()가 반환됨
System.out.println(optionalName); // 출력: Optional.empty
Optional.ofNullable()
의 실적용Todo todo = todoRepository.findByIdWithUser(todoId).orElseThrow();
findByIdWithUser()
메서드는 Optional<Todo>
를 반환하고, 데이터가 없으면 Optional.empty()
를 반환..orElseThrow()
는 Optional
이 비어있는 경우(데이터가 없을 때), NoSuchElementException
과 같은 예외를 던짐하지만, 만약 우리가 QueryDSL을 사용해 fetchOne()
을 호출하는 경우, fetchOne()
이 데이터가 없을 때 null을 반환한다. 여기서 직접적으로 null을 반환하는 경우를 처리하지 않으면 NPE가 발생할 수 있다.
Optional.ofNullable()
적용한 코드@Override
public Optional<Todo> findByIdWithUserDSL(Long todoId) {
return Optional.ofNullable(
queryFactory
.select(todo)
.join(todo.user, user).fetchJoin() // Todo와 User를 함께 조회
.from(todo)
.where(todo.id.eq(todoId))
.fetchOne() // 데이터가 없으면 null 반환
);
}
Optional.ofNullable()
로 감싸서 null
인 경우에는 Optional.empty()가 반환되도록 처리이제 findByIdWithUserDSL()
메서드는 항상 Optional<Todo>
를 반환하게 되고, 그 결과를 받아서 안전하게 처리할 수 있게됨.
Optional.ofNullable()
vs Optional.of()
Optional.of()
: null이 아닌 값을 감쌀 때만 사용. 만약 null을 전달하면 NullPointerException
이 발생.Optional<String> name = Optional.of(null); // NPE 발생
Optional.ofNullable()
: null이 있을 수도 있고, 없을 수도 있는 상황에서 사용. null이 들어오면 Optional.empty()
를 반환.Optional.ofNullable()
은 값이 null일 수 있는 상황에서 안전하게 값을 감싸기 위해 사용.fetchOne()
)의 결과를 안전하게 처리하기 위해 Optional.ofNullable()
을 사용하면 NPE를 방지할 수 있음.