[Java] Optional이란?
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 메소드
참고링크
- https://mangkyu.tistory.com/70?category=872426
- http://tcpschool.com/java/java_stream_optional