자바 Spring공부를 하다가 Optional이라는 클래스를 처음봐서 따로 어떤 역할을 하는 클래스인지 찾아보았다. 강의에서 사용한 코드는 다음과 같다.
@Override
public Optional<Member> findById(Long id) {
return Optional.ofNullable(store.get(id));
}
Optional<T> 클래스는 T타입의 객체를 포장해주는 Wrapper class이다. 보통 어떤 객체의 값에 null이 올 수 있으면 항상 null예외처리(NullPointerException)를 해줘야하는데 Optional을 이용하면 이를 쉽게 처리를 할 수 있다.
Optional객체를 만드는 방법에는 3가지가 있다.
1. Optional.empty();
Optional.empty()는 그냥 빈 Optional객체를 생성한다.
2. Optional.of(T value)
Optional.of()로 객체를 저장할때는 절대 null이 올 수 없는 객체를 대상으로 해야한다. 만약 null이 오는 객체를 저장하면 NullPointerException 예외가 발생한다.
3. Optinoal.Nullable(T value)
Optional.of()와 달리 Optional.Nullable()에는 null 값이 객체에 들어있다고 해도 객체를 저장할때 NullPointerException 예외가 발생하지 않는다. 대신 null값이 들어있는경우 비어있는 Optional객체(Optional.empty())가 생성된다.
이렇게 생성한 Optional 객체를 이용하는 법도 알아보자
1. isPresent()
isPresent()는 Optional이 비어있는지 판단하여 true와 false를 반환한다. 이때 Optional에 저장된 객체의 값이 null이면 Optional이 비어있게되고 아니면 값이 존재하므로 객체의 값이 null인지 아닌지를 알 수 있다.
2. ifPresent(Consumer <? super T> action)
ifPresent()는 Optional이 값을 갖고있으면 인자로 받은 람다식에 그 값을 적용해준다. 만약 Optional이 비어있으면 람다식이 실행되지 않는다.
3. orElse(T other)
orElse는 만약 Optional이 비어있다면 orElse()안에있는 값을 넘긴다. 예를들면 아래와 같다.
String str = "Good";
name = Optional.ofNullable(str).orElse("test");
System.out.println(name);
다음의 경우 Optional은 str이 null이 아니므로 name에 "Good"이 들어가지만 만약 null이였다면 "test"가 name에 들어가게 된다.
4. orElseGet(Supplier<? extends T> supplier)
orElseGet은 orElse와 비슷하지만 받는 인자가 다르다. 만약 Optional이 비어있다면 인자로 받은 Supplier 함수형 인터페이스를 실행한다. 다음과같은 코드에서 orElse와 orElseGet이 어떻게 실행되는지 확인해보자.
public String getName() {
System.out.println("getName 실행");
return "";
}
String name1 = Optional.ofNullable("Good").orElse(getName());
String name2 = Optional.ofNullable("Good").orElseGet(() -> getName());
System.out.println("name1 = " + name1);
System.out.println("name2 = " + name2);
//출력 결과
//getName 실행
//name1 = Good
//name2 = Good
orElse의 경우에는 Optional이 비어있지 않아도 getName()을 실행시켜버린다. 하지만 orElseGet()의 경우에는 getName()을 실행시키지 않고 지나간다. 이렇게 orElse()는 Optional이 비어있던 아니던 인수로 받은 변수를 무조건 실행시키고 orElseGet()의 경우에는 Optional이 비어있는 경우만 인수로 받은 람다식을 실행시킨다.
5. orElseThrow(Supplier<? extends X> exceptionSupplier)
orElseThrow()는 Optional 객체가 비어있다면 인수로 저장된 예외를 발생시킨다.
reference.
- https://stir.tistory.com/140