java.util.Optional
Java8에서 등장!
null
이 나올수 있는 객체를 감싸서
null이 나올 수 있는 객체를 더욱 안전하게 사용
할 수 있게 해주는 클래스이다.
Optional<T>
형태로 사용하는데 ,
이것은 T 객체가 null을 반환할 가능성이 있음
을 명확하게 나타낸다.
Optional 클래스를 사용함으로써 NullPointerException
에러를 방어할 수 있다.
public interface AccountRepository {
Optional<Account> findFirstByOrderByIdDesc();
}
T 자료형인 value가 null이 아닌 경우
반환 값
: Optinal<T>
T 자료형인 value가 null인 경우
반환 값
: NullPointerException
반환 값
: Optinal<T>
Optional<T>.map(Function<? super T, ? extends U> mapper)
.map( ) 앞에 붙은 Optional 객체에 값이 존재하면
주어진 함수를 적용하여 새로운 Optional 객체를 반환한다.
// 사용된 메서드 정보
// 이름 : accountRepository.findFirstByOrderByIdDesc()
// 반환타입 : Optional<Account>
accountRepository.findFirstByOrderByIdDesc()
.map(account -> (Integer.parseInt(account.getAccountNumber())) + 1)
이 때 map의 반환 타입은 Optional<Integer>
accountRepository.findFirstByOrderByIdDesc()
.map(account -> String.valueOf(Integer.parseInt(account.getAccountNumber())) + 1))
이 때 map의 반환 타입은 Optional<String>
Optional<T>.method(return U).orElse(U other)
method의 반환 자료형이 U
인데,
U
자료형인 값이 정상적으로 반환되면 orElse()는 실행되지 않는다.
method의 반환값이 null
이거나 Optional.empty()
인 경우
orElse()의 other
을 반환한다.
// 사용된 메서드 정보
// 이름 : accountRepository.findFirstByOrderByIdDesc()
// 반환타입 : Optional<Account>
String newAccountNumber = accountRepository.findFirstByOrderByIdDesc()
.map(account -> String.valueOf((Integer.parseInt(account.getAccountNumber())) + 1))
.orElse("1000000000");
이 경우 map()의 반환 값이 null이 나오면 orElse의 "1000000000
" 값을 출력
Optional.empty().orElse("Hello, Default!"));
이 경우 .orElse() 앞에서 비어있는 Optional 객체를 반환하기 때문에, Hello, Default!
출력
Optional<T>.method(return U).orElseThrow(Supplier<? extends X> exceptionSupplier)
method의 값이 존재하면 반환
method의 값이 없으면 .orElseThrow()에 넣어둔 예외를 던진다.
// 사용된 메서드 정보
// 이름 : accountUserRepository.findById(Long value)
// 반환타입 : Optional<AccountUser>
accountUserRepository.findById(userId)
.orElseThrow(() -> new AccountException(ErrorCode.USER_NOT_FOUND));
이 경우 findById()의 반환 값이 null
이 나오면
orElseThrow() 에 넣어둔 사용자 정의 Exception
( 여기서는 AccountException )을 발생시킨다.
Optional<T>.method(return U).ifPresent(Consumer<? super T> consumer)
method의 값이 존재하는 경우
ifPresent에 주어진 작업을 반환한다.
Optional.of("Hello, World!")
.ifPresent(System.out::println);
이 경우 "Hello, World!"를 콘솔에 출력한다.
Optional<T>.method(return U).filter(Predicate<? super T> predicate)
method의 값이 존재 ifPresent에 주어진 작업을 반환한다.
Optional.of("Hello, World!")
.filter(val -> val.startsWith("Hello"))
.orElse("Filtered out");
이 경우 val이 "Hello"로 시작하는지 filter()로 검열하는 조건에 부합하기 때문에
orElse는 무시되고 "Hello, World!"가 반환된다.
아아아아악
인터페이스 공부 제대로 안했더니
Optional 내용 정리하는데 너무 오래걸렸다.
내일은 인터페이스 공부 다시 해야겠다