목차
개요
스프링 그리고 Java를 사용하다 보면 null 값 핸들링이 무척 중요하다는 사실을 깨닫고 적절한 처리에 대해 고민을 하게 된다.
특히 NullPointerException의 발생 또한 자주 접하게 된다. Java에서는 이러한 문제를 해결하기 위해 Optional 클래스를 도입했다.
래퍼런스에 따르면 Optional<T>는 값(T 타입)을 포함할 수도, 포함하지 않을 수도 있다고 한다. 따라서 이 클래스는 값의 존재 여부에 따라 여러 유용한 메서드를 제공하며, 이를 통해 null 값 관련 이슈를 안정적으로 처리할 수 있게 된다.
래퍼런스를 참조하면 총 세가지의 메서드를 소개해주고 있는데
isPresent(): 값이 존재하는지 여부를 확인하는 메서드
get(): 값이 존재할 경우 해당 값을 반환
orElse(), orElseGet(), orElseThrow(): 값의 존재 여부에 따라 다른 동작을 수행하는 메서드
자주 사용하는 종류는 이렇게 크게 세가지 인것 같다.
이번 포스팅에서는 Java의 Optional 클래스의 핵심 메서드 중에서도 orElse, orElseGet, orElseThrow의 사용법과 차이점에 대해 자세히 알아보자
orElse와 orElseGet 의 차이
orElse는 Optional 객체가 값이 포함되어 있지 않을 때, 반환할 기본 값을 직접 전달한다.
Optional<String> optional = Optional.ofNullable(null);
String result = optional.orElse("Default Value");
System.out.println(result); // 출력: Default Value
orElse 내부의 연산(즉, 인수로 전달된 값)은 Optional의 값의 존재 여부와 상관없이 항상 평가된다.
Optional<String> optional = Optional.ofNullable(null);
String result = optional.orElseGet(() -> {
// 여기서의 연산은 값이 없는 경우에만 실행됩니다.
return "Generated Default Value";
});
System.out.println(result); // 출력: Generated Default Value
orElseGet은 Supplier 혹은 람다 표현식을 통해 제공된 값을 반환한다. 중요한 점은 값이 없는 경우에만 해당 Supplier 혹은 람다 표현식이 실행된다는 것이다.
따라서 정리하자면 둘의 차이점은
public T orElse(T other)
public T orElseGet(Supplier<? extends T> other)
orElse는 바로 값을 받기에 복잡한 계산이나 연산을 필요로 하는 경우에는 그 연산이 무조건 실행되고
orElseGet은 Supplier<T> 타입의 인자를 받아서 Optional 값이 없을 때만 해당 Supplier (람다식이나 메서드 참조)를 실행한다.
만일 orElse 에 지정되어있는 연산이 많은 자원을 필요로 하는 연산이라면 orElse는 불필요한 연산을 하기위해서 자원과 시간을 낭비하게 될 것이다.
구체적인 성능차이 또한 Baeldung 에서 측정해본 결과 orElseGet이 더 뛰어난 성능을 가짐을 확인할 수 있었다.
https://www.baeldung.com/java-optional-or-else-vs-or-else-get
orElseThrow
orElseThrow는 orElseGet과 비슷하게 Optional 객체가 비어 있을 경우, Supplier 혹은 람다 표현식을 통해 제공된 예외를 발생시킨다.
Optional<String> optional = Optional.ofNullable(null);
String result = optional.orElseThrow(() -> new NoSuchElementException("No value present!"));
예외 공급자가 null일 경우 NullPointerException이 발생한다. 따라서 예외를 제공할 때는 항상 유효한 예외 객체를 반환해야 합니다.
마무리
따라서 결론적으로 orElse()를 사용하면 기본 객체를 불필요하게 생성할 수도 있기에 요구 사항이나 코드의 맥락에 따라 orElse()와 orElseGet() 중 어느 것을 사용할지 결정해야 한다.
추가적으로 멘토분께서 조언해주신 내용을 첨부하고 포스팅 마무리하겠다.
'Java' 카테고리의 다른 글
JVM스택메모리 구조 이해를 위한 바이트코드 예시 (0) | 2024.06.25 |
---|---|
JVM에서 자바 메서드와 네이티브 메서드 실행의 차이점 (0) | 2024.06.24 |
객체지향에서의 클래스 간의 관계[IS, HAS, USES, REALIZE,DEPEND-ON] (0) | 2023.04.28 |
문자열 조작에 있어서 오버헤드 발생 이유 (StringBuffer, StringBuilder 차이) (0) | 2023.04.14 |
자바표준(JLS)으로 알아보는 기본 생성자, 캡슐화, 유연성, 로직 중앙화 (0) | 2023.04.12 |