Java Optional 개념 및 사용법
목차
개발을 하다 보면 NullPointException(NPE)을 만나게 된다. 가장 많이 발생하는 에러 중 하나라고 하는데, 이를 피하기 위해선 null을 체크하는 로직이 추가되어야 한다.
DeviceVo deviceVo = deviceDao.findById(deviceId);
deviceVo.getName(); // deviceVo가 null이면 NullPointException 발생
if(deviceVo != null){
deviceVo.getName();
if(deviceVo.getModel() != null) {
deviceVo.getModel().getModelId();
}
}null 체크해야 될 부분이 많다면 코드가 복잡해져 가독성이 떨어지는 단점이 있다.
Java 8에서는 Optional<T> 클래스를 도입하였는데, null이 될 수도 있는 객체를 감싸고 있는 Wrapper 클래스이다. Optional로 객체를 감싸서 사용하게 되면 NPE 방지를 위해 null 체크를 직접 하지 않아도 된다.
Optional 생성
빈 Optional 객체는 아래와 같이 생성 할 수 있다.
Optional<String> optional = Optional.empty();
System.out.println(optional); // Optional.empty
System.out.println(optional.isPresent()); // falseof() 메서드는 value가 null인 경우 NPE를 발생시킨다. 반드시 값이 있는 경우에만 사용할 것.
Optional<String> optional = Optional.of(value);ofNullable() 메서드는 value가 null일 경우 NPE 대신 Optional.empty를 반환한다.
Optional<String> optional = Optional.ofNullable(value);
System.out.println(optional); // Optional.emptyOptional 메서드
- filter() : 람다식이 true면 Optional 객체를 그대로, false이면 Optional.empty()를 리턴한다.
String result1 = Optional.of("ABCDE")
.filter((val) -> val.contains("ABC"))
.orElse("Does not contain ABC");
System.out.println(result1); //ABCDE
String result2 = Optional.of("CDEFG")
.filter((val) -> val.contains("ABC"))
.orElse("Does not contain ABC");
System.out.println(result2); //Does not contain ABC- map() : 입력값을 다른값으로 변환하는 메서드
String result3 = Optional.of("abcde")
.map(String::toUpperCase)
.orElse("fail");
System.out.println(result3); //ABCDE- isPresent() : 값의 유무에 따라 true, false 반환
- ifPresent() : 람다식을 인자로 받아 값이 있을때만 람다식이 실행됨
Optional.of("ABCDE")
.ifPresent(System.out::println); // ABCDE
Optional.ofNullable(null)
.ifPresent(System.out::println); // 아무것도 출력되지 않음- get() : Optional 객체의 value를 가져온다. 값이 없으면 NoSuchElementException 발생
- orElse() : Optional 객체가 비었다면 실행된다.
String result2 = Optional.of("CDEFG")
.filter((val) -> val.contains("ABC"))
.orElse("Does not contain ABC");
System.out.println(result2); //Does not contain ABC- orElseGet() : Optional 객체가 비었다면 기본값으로 제공할 supplier를 지정한다. orElse()는 null 여부와 상관없이 항상 호출되며, orElseGet()은 null일때만 호출된다.
- orElseThrow() : Optional 객체가 비어있다면 예외를 발생시킨다.
String result1 = Optional.of("CDEFG")
.filter((val) -> val.contains("ABC"))
.orElseThrow(NoSuchElementException::new);