its_jh_stroy

[Java] Optional<T> 타입 본문

Java

[Java] Optional<T> 타입

_J_H_ 2024. 7. 25. 22:41

Optional 타입은 스프링부트를 다루다보면 자주 나오는 타입이다.

나중에 한 번 정리해야지 미루고 있다가 이번 기회에 가볍게라도 정리해보려고 한다.

 

Optional<T>

자바 공식 문서에 나와있는 Optional<T> 타입에 대한 설명이다.

A container object which may or may not contain a non-null value.

 

Optional<T> 타입은 null을 포함할 수 있는 타입이다.

 

아래와 같이 자바에서는 기본 타입에 null을 할당할 수 없다.

// Type mismatch: cannot convert from null to int
int a = null;

 

 

개발 중 값을 주고받다 보면 변수에 null이 들어가는 경우도 있는데 그런 상황에서 사용될 수 있다.

대표적으로 스프링부트에서 JPA를 사용할 때, findById 메서드가 Optional<T> 타입을 반환한다.

Optional<Item> result = itemRepository.findById(id);

 

 

get

Optional<T> 타입의 값을 가져오기 위해서는 get 메서드를 사용한다.

만약 null 값을 가지는데 get 메서드를 호출할 경우, NullPointerException 예외가 발생한다.

따라서 값을 가져올 때는 null이 할당되었는지 확인해야 한다.

Optional<Item> result = itemRepository.findById(id);
if (result.isEmpty()) {
	System.out.println(result.get());
}

 

 

orElse와 orElseGet

null인 경우 매개변수로 전달된 값을 반환한다.

orElse는 매개변수로 값을 입력하고 항상 값을 가져온다.

orElseGet는 매개변수로 Supplier 타입 함수를 전달하고, 값이 null인 경우에만 호출한다.

public void test() {
	// Optional 타입을 생성하는 메서드
	Optional<Integer> a = Optional.of(2);
	int num1 = a.orElse(getNum());
	System.out.println(num1);
	int num2 = a.orElseGet(this::getNum);
	System.out.println(num2);
	// Called getNum
	// 2
	// 2

	Optional<Integer> b = Optional.ofNullable(null);	
	int num3 = b.orElse(getNum());
	System.out.println(num3);
	int num4 = b.orElseGet(this::getNum);
	System.out.println(num4);
	// Called getNum
	// 45
	// Called getNum
	// 45
}

public int getNum() {
	System.out.println("Called getNum");
	return 45;
}