JAVA Optional
T type의 객체를 포장해주는 래퍼 클래스이다.
Optional 인스턴스는 모든 타입의 참조변수를 저장할 수 있다.
null 일 수도 있는 객체를 감싸고 있다.
Optional을 쓰는 이유
- NullPointerException을 직접 다루지 않아도 된다.
- null 체크를 직접 하지 않아도 된다.
- null일 수도 있다는 가능성을 담고 있기 때문에 방어로직을 줄일 수 있다.
Optional 초기화 하기
Optiona.empty()
Optional<Address> addressOptional = Optional.empty();
empty()를 통해서 초기화하면 비어있는 Optional 객체를 가지고 온다.
Optional.of(value)
Address addr = new Address();
Optional<Address> test = Optional.of(addr);
value 값이 null이 아닌 경우에 사용한다. null 이 들어갈 경우 NPE가 발생한다.
Optional.ofNullable(value)
Optional<Address> test = Optional.ofNullable(addr);
null인지 아닌지 확실하지 않은 경우에 사용한다.
null이 넘어올 경우에 empty 객체를 반환한다.
Optional 객체에 접근하기
optional객체는 다양한 인스턴스 메소드를 제공한다.
Optional이 담고 있는 객체가 있을 경우 값을 반환하고 null일 경우에는 다르게 동작한다.
get()
Optional get() 메소드를 통해 객체에 접근할 수 있다. 단 비어있을 경우 NoSuchElementException을 던지기 때문에 반드시 값이 있는지 확인하고 사용해야 한다.
Optional<Address> addressOptional = Optional.ofNullable(addr);
if(addressOptional.isPresent()) {
System.out.println(addressOptional.get().getSi());
}
isPresent()
객체가 비어있는지 확인한다.
비어있으면 false, 비어있지 않으면 true
orElse()
비어있는 Optional객체에 대해서 넘어온 인자를 반환한다.
null일 경우 인자를 리턴한다.
String orElseString = "aaaa";
Optional<String> strOptional = Optional.ofNullable(null);
System.out.println(strOptional.isPresent());
// 비어있으므로 false가 출력됨
String result = strOptional.orElse(orElseString);
System.out.println(result);
// aaaa 출력
orElseGet()
비어있는 Optional 객체에 대해서 넘어온 함수형 인자를 통해 생성된 객체를 반환한다.
메서드를 인자로 받고 함수에서 반환한 값을 반환한다.
public void orElseGet() {
Optional<String> strOptional = Optional.ofNullable(null);
String result = strOptional.orElseGet(this::getInitValue);
System.out.println(result);
//init 출력
}
private String getInitValue() {
return "init";
}
orElse와 orElseGet의 차이점은 orElse()는 null이 아니어도 실행하고 orElseGet()은 null일때만 실행한다.
orElseThrow()
null일 경우에 예외를 던질 수 있다.
Optional<String> strOptional = Optional.ofNullable(null);
strOptional.orElseThrow();
strOptional.orElseThrow(NullPointerException::new);
map()
요소 값의 형태를 바꾸는 stream api다.
String phoneNumber = Optional.ofNullable(addr)
.map(Address::getMemeber)
.map(Memeber::getPhone)
.map(Phone::getNumber)
.orElse("1010");
Address 객체가 null인지 체크한 다음 Address 객체의 getMember를 통해 Member객체에접근한다.
그리고 Member의 getPhone 메소드를 통해 Phone객체에 접근해서 최종적으로 number를 가져온다.
number가 null일 경우 1010을 가져온다.
Address(getMember) => Member (getPhone) => Phone(getNumber)
중간에 Member나 Phone이 null이어도 1010을 리턴한다.
List<String> arrList = Arrays.asList("apple", "lemon", "peach");
int size = Optional.of(arrList).map(List::size).orElse(0);
기존에 있던 객체도 사용이 가능하다.
filter()
조건에 따라서 요건을 필터링 할 수 있다.
predicate함수의 결과가 true인 것만 새로운 Stream API로 반환하는 API다.
boolean result = Optional.ofNullable(mem)
.filter(s -> s.getName().contains("a"))
.isPresent();
'Java' 카테고리의 다른 글
JAVA 직렬화란? 직렬화 사용이유 (0) | 2022.02.02 |
---|---|
java static 사용이유 생성자 대신 static 팩토리 메소드 (0) | 2021.12.18 |
JAVA Stream API 란? (0) | 2021.02.02 |
JAVA lamda란 (0) | 2021.01.29 |
JAVA ClassLoader 란 ? (0) | 2020.12.22 |