공부공부/Java

[Java] Optional이란?

이숭간 2021. 5. 24. 00:06
728x90

Optional

Java8부터 Optional<T>클래스를 사용해 NullPointerException(이하 NPE)를 방지할수 있도록 했다.

Optional<T> 클래스는 Integer나 Double클래스처럼 T타입의 객체를 포장해주는 래퍼클래스이다.

 

Optional<T>는 null이 올수 있는 값을 감싸는 Wrapper클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다.

즉, 예상치못한 NPE예외를 제공되는 메소드로 간단히 회피할 수 있어 복잡한 조건문 없이도 null값으로 인해 발생하는 예외를 처리할 수 있다.

public final class Optional<T> {
 
  // If non-null, the value; if null, indicates no value is present
  private final T value;
   
  ...
}
출처: https://mangkyu.tistory.com/70?category=872426 [MangKyu's Diary]

 

Optional 사용법

[Optional 객체의 생성]

of()메소드나 ofNullable()메소드를 사용해서 Optional객체를 생성할 수 있다.

null발생 가능성이 있는 값이라면 ofNullable()을 통해 생성해야 NPE를 발생시키지 않는다.

이때 명시된 값이 null이면 비어있는 Optional객체를 반환한다.

 

그리고 orElse 또는 orElseGet메소드를 이용해 null인 경우에도 안전하게 값을 가져올 수 있다.

// Optional의 value는 값이 있을 수도 있고 null 일 수도 있다.
Optional<String> optional = Optional.ofNullable(getName());
String name = optional.orElse("anonymous"); // 값이 없다면 "anonymous" 를 리턴

출처: https://mangkyu.tistory.com/70?category=872426 [MangKyu's Diary]

 

[Optioanl 객체에 접근]

get()메소드를 사용하면 Optional객체에 저장된 값에 접근할 수 있다.

만약 Optional객체에 저장된 값이 null이면, NoSuchElementException예외가 발생한다.

따라서 get()메소드를 호출하기 전에 isPresent()메소드를 사용하여 Optional객체에 저장된 값이 null인지 아닌지를 먼저 확인한 후에 호출하는것이 좋다.

Optional<String> opt = Optional.ofNullable("자바 Optional 객체");

if(opt.isPresent()) {

    System.out.println(opt.get());

}

 

[orElse~~()]

다음과 같은 메소드를 이용하면 null대신에 대체할 값을 지정할 수 있다.

1. orElse() : 저정된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환

2. orElseGet() : 저정된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다표현식의 결과값을 반환

3. orElsetThrow() : 저정된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생

 

 

[ orElse와 orElseGet의 차이]

  • orElse : 값이 null이든 아니든 호출된다. 매개변수로 값을 취한다.
  • orElseGet : 값이 null일때만 호출된다. 매개변수로 Supplier를 취한다. 

 

[JpaRepository에서 findBy~ 메서드는 Optional을 리턴한다.]

	/**
	 * Retrieves an entity by its id.
	 *
	 * @param id must not be {@literal null}.
	 * @return the entity with the given id or {@literal Optional#empty()} if none found.
	 * @throws IllegalArgumentException if {@literal id} is {@literal null}.
	 */
	Optional<T> findById(ID id);

 

// Optional로 값을 리턴하기때문에 null일경우 exception을 날리고 아닌경우에 객체를 받을수있다.
Post post = postsRepository.findById(id)
                .orElseThrow(() -> new PostNotFoundException(id));

 

Optional 메소드

출처 : http://tcpschool.com/java/java_stream_optional

 

참고링크