Optional은 자바 8 버전부터 추가된 기능으로 Optional클래스를 사용해 Null 예외를 방지할 수 있도록 도와준다.
도와주는 방법은 변수 자체를 사용하는 것이 아니라 클래스 내부에 null이 올 수 있는 값을 감싼 Wrapper 클래스로 참조하더라도 Null 예외가 발생하지 않는다.
또한 클래스 자체적으로 각종 메서드들을 제공해준다.
empty(): 비어있는 Optional 객체를 반환합니다.
of(value): null이 아닌 값을 갖는 Optional 객체를 반환합니다. 값이 null이면 NullPointerException을 발생시킵니다.
ofNullable(value): 값이 null일 수도 있는 객체를 위한 Optional 객체를 반환합니다. 값이 null이면 비어있는 Optional을 반환합니다.
get(): 값이 존재하면 해당 값을 반환하고, 값이 없으면 NoSuchElementException을 발생시킵니다.
orElse(defaultValue): 값이 존재하면 해당 값을 반환하고, 값이 없으면 기본값을 반환합니다.
orElseGet(supplier): 값이 존재하면 해당 값을 반환하고, 값이 없으면 주어진 Supplier 인터페이스의 구현을 통해 생성된 값을 반환합니다.
ifPresent(consumer): 값이 존재하면 주어진 Consumer 인터페이스의 구현을 실행합니다.
예시를 위해 게시판을 만들 때 사용할 PostService파일에 들어갈
view 메서드를 분해해보자.
package org.example.simpleboard.post.service;
import lombok.RequiredArgsConstructor;
import org.example.simpleboard.post.db.PostEntity;
import org.example.simpleboard.post.db.PostRepository;
import org.example.simpleboard.post.model.PostRequest;
import org.example.simpleboard.post.model.PostViewRequest;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service
@RequiredArgsConstructor
public class PostService {
private final PostRepository postRepository;
/*
* 1. 게시글이 있는가?
* 2. 비밀번호가 맞는가?
* */
public PostEntity view(PostViewRequest postViewRequest) {
//요청 본문이 들어오면 JpaRepository를 활용해
return postRepository
.findById(postViewRequest.getPostId()) //findById는 옵셔널(반복적인 null check 가능)
.map(data->{
if(!data.getPassword().equals(postViewRequest.getPassword())){
var format ="패스워드가 맞지 않습니다. %s vs %s";
throw new RuntimeException(String.format(format, data.getPassword(),postViewRequest.getPassword()));
}
return data;
}).orElseThrow( //findById가 옵셔널이기 때문에 orElseThrow를 던져줄 수 있다. (null일 때를 대비할 수 있다.)
()->{
return new RuntimeException("해당 게시글이 존재하지 않습니다."+postViewRequest.getPostId());
}
);
}
}
findById는 Optional을 반환하기 때문에 아래의 orElseThrow로 예외 처리를 안전하게 할 수 있다.
그 이외의 findById에 파라미터로 전달되는 내용은 들어온 비밀번호가 유효한지 판별하는 코드이다.