Optional이란?
Java8부터 지원하는 Optional class에 대해 기록하려고 한다.
개발하다 보면 정말 자주 만나게 되는 예외가 바로 NPE(NullpointerException)다.
NPE를 내뱉지 않게 하려면 null-safe하게 만들기 위해 null여부를 꼼꼼하게 검사해야 된다.
하지만 그렇게 하다보면 코드가 복잡해지고, 가독성은 떨어지고, 각 변수마다 null값 체크하다보면 프로그래머의 실수로 놓치는 부분이 생길 수 있다.
Optional<T>는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다.
Optional 을 이용하면 위 문제들을 해결할 뿐만 아니라, 가독성 좋고 NPE를 방지하는 코드를 만들 수 있다.
Optional 활용하기
✔️Optional 생성
📌Optional.empty() - 값이 null일 때 빈 객체 생
Optioanl은 Wrapper클래스 라서 값이 null일 수 있다. 이때 Optional의 empty()메소드로 생성 가능하다.
Optional<Member> result = Optional.empty(); // 빈Optional 객체 리턴
📌Optional.of() - 값이 null이 아닌 경우
만약 어떤 객체가 절~대 null이 아니라면 of()로 생성 가능하다.
단, null 값을 of()메서드의 인자로 받을 경우 NullpointerException을 일으킨다.
String name1 = "Zoe";
Optional<String> opt = Optional.of(name1);
String name2 = null;
Optional<String> opt = Optional.of(name2); // NPE 발생
📌Optional.ofNullable() - 값이 null일 수도, 아닐 수도 있는 경우
ofNullable()은 일반 객체뿐만 아니라 null값도 인자로 받을 수 있다.
그리고 생성 이후에 orElse() 또는 orElseGet()메소드를 이용해서 값이 없을 때도 안전하게 값을 가져올 수 있다.
Optional<String> optional = Optional.ofNullable(getName());
String name = optional.orElse("이름 없음"); // 값이 없다면 "이름 없음" 를 리턴
✔️orElse, orElseGet으로 값 가져오기
📌orElse()
- Optional객체가 비어있다면 인자가 리턴됨.
- null값의 유무와 상관없이 항상 호출.
📌orElseGet()
- 값이 null일 경우에만 orElseGet에 인자로 주어진 함수를 실행.
- 값이 미리 존재하지 않는 거의 대부분의 경우 이것 사용.
정리된 내용처럼, orElse() 메소드는 항상 인자 평가가 발생한다. 따라서 객체 생성 비용이 orElseGet()보다 크기 때문에,적재적소에 사용해야 한다.
✔️orElseThrow()로 예외 발생
- Optional객체가 비어있다면, Supplier 함수를 실행해 예외 발생시킨다.
- 자바10에서는 매개변수가 없는 orElseThrow()도 제공해준다.
Optional.ofNullable(something).orElseThrow(NoSuchElementException::new);
// 예제 (자바 10)
Optional.ofNullable(something).orElseThrow();
✔️ifPresent
- 값이 비어있지 않다면 이 값을 가지고 원하는 작업을 수행할 수 있다.
비어있는 Optional 객체를 받으면 ifPresent()의 메서드를 수행하지 않는다.
// 예제1
Optional.of("TEST").ifPresent((value) -> {
// 수행 작업
});
// 예제2 (null이면 ifPresent 미수행 예시)
Optional.ofNullable(null).ifPresent((value) -> {
// 수행 작업
});
✔️isPresent
- 최종적으로 객체가 존재하는 여부를 판별한다. boolean 으로 리턴.
Optional.ofNullable("TEST").isPresent(); // true
Optional.ofNullable("TEST").filter((val) -> "test".eqauls(val)).isPresent(); // false
✔️get
- 연산 끝낸 후 객체를 꺼낸다. 비어있는 객체라면 예외 발생(NoSuchElementException).
Optional.of("TEST").get(); // 'TEST'
Optional.ofNullable(null).get(); // NoSuchElementException 발생
'Back > Java' 카테고리의 다른 글
[JAVA] 파일 관련 Stream, I/O 성능 개선 (File 복사 기능) (2) | 2024.07.24 |
---|---|
[JAVA] Stream Collectors.groupingBy 널(null) 사용하기 (0) | 2023.04.07 |
[Java] Stream 스트림으로 중복 값 찾기 (0) | 2023.02.22 |
[JAVA] Reflection 이용해서 필드값 set 하기 (0) | 2022.04.11 |
[JAVA] 데이터 직렬화(serialization) 하는 이유 (0) | 2022.02.11 |
댓글