본문 바로가기
☕️자바 𝗝𝗔𝗩𝗔

[JAVA] Optional 클래스

by 비타민찌 2022. 10. 6.
728x90

Spring Data JPA를 사용하며 CrudRepository의 findById 메서드 리턴 타입인 Optional 클래스를 살펴보았다.

 

Optional은 Java 8에 추가된 새로운 API이며 'null일 수도 있는 객체'를 감싸는 일종의 Wrapper 클래스로, 여러 if 로직 대신 언어 차원에서 null 문제를 해결할 수 있게 해준다. 한마디로 null 처리를 세련되게 다룰 수 있게 도와주는 녀석이다.

Optional<T> optional

이러한 optional 변수 내부에는 null이 아닌 T 객체가 있을 수도 있고 null이 있을 수도 있다. Optional 클래스는 여러 가지 API를 제공하여 null일 수도 있는 객체를 다룰 수 있도록 돕는다.

 

null 처리를 세련되게 다룰 수 있다고 했는데, 이 말에 두 가지 물음표를 달 수 있다. 왜 null 처리를 세련되게 해야하나? 어떻게?

우선 NullPointerException를 피해야 하기 때문이다. NullPointerException과 같은 실행 중단은 실제 운영중인 서비스에 있어 치명적인 상황을 불러 일으킨다. 따라서 이렇게 NullPointerException이 발생할만한 상황을 예측하여 if문 등을 사용해 null 처리를 했었다.

if(a!=null) {
	return a;
	}
return "a is null";

하지만 이와 같은 방법은 NullPointerException이 발생할만한 모든 상황을 예측해야 하며, if문 등을 통한 null 처리는 핵심 로직과 관련된 코드의 가독성을 해칠 수 있다는 문제가 있다.

 

그럼 이제 Optional<T> findById(ID id) CrudRepository의 findById를 살펴보는 것으로 Optional에 대해 간단하게 살펴보자.

findById는 Entity의 id로 검색을 해서, Optional<T>를 리턴 타입으로 반환하는 메서드이다. 따라서 다음과 같이 isPresent() 를 이용하여 Optional 내부에 객체가 들어있는지 확인한 후에 get()을 이용해 반환된 객체를 꺼내 쓸 수 있다.

 

 

 

1. Optional 객체 생성

📍Optional.empty() :

비어있는 Optional 객체로 생성한다. 따라서 이 내부에 있는 Member 객체는 null이고, 이 객체는 Optional 내부적으로 미리 생성해놓은 Singleton 인스턴스이다.

Optional<Member> optionalMember = Optional.empty();

 

📍Optional.of(value) :

인자 value를 담고 있는 Optional 객체로 생성한다. 이 객체는 미리 만들어 놓은 null이 아닌 객체를 넘기면 되는데, 만약 인자로 넘긴 객체가 null이라면 NullPointerException이 발생할 수 있다.

Optional<Member> optionalMember = Optional.value(member);

 

📍Optional.ofNullable(value) :

null일 수도 있고 아닐 수도 있는 객체를 담아 Optional 객체를 생성합니다. 만약 member가 null인지 null이 아닌지 확신이 서지 않는다면 이 방법으로 Optional 객체를 생성하면 됩니다.

Optional<Member> optionalMember = Optional.ofNullable(member);

 

2. Optional 객체 접근

📍get() :

Optional 내부에 담긴 객체를 반환한다. 만약, null인 객체라면 NoSuchElementException이 발생한다. 따라서, isPresent() 로 체크한 후에 이 get 메서드를 사용한다.

Member member = optionalMember.get();

Optional 내부에 담긴 객체가 null이 아니라면 담겨 있는 객체를 반환하고, null이라면 인자로 넘겨준 함수형 인자를 통해 생성된 예외를 발생시킨다.

Member member = optionalMember.orElseThrow(NullPointerException::new);

 

📍orElse(T other) :

Optional 내부에 담긴 객체가 null이 아니라면 담겨있는 객체를 반환하고, null이라면 인자로 넘겨준 member1이라는 객체를 반환합니다.

Member member = optionalMember.orElse(member1);

 

📍orElseGet(Supplier<? extends T> other) :

Optional 내부에 담긴 객체가 null이 아니라면 담겨있는 객체를 반환하고, null이라면 인자로 넘겨준 함수형 인자를 통해 생성된 객체를 반환한다.

 

 

 

 

https://www.inflearn.com/questions/90949

https://dbbymoon.tistory.com/3

728x90

댓글