[ Java ] Optional
Optional
Optional은 Java 8부터 도입된 클래스로, 값의 존재 여부를 나타내는 래퍼 클래스이다. 이 클래스는 주로 값이 존재하지 않을 수 있는 상황(null)에서 null 대신 사용되어 코드의 안전성을 높이고 NPE예외를 방지한다. 따라서, Optional을 사용함으로써 코드를 더 명확하게 작성하고 예외 처리를 개선할 수 있다.
- Optional은 Java 8부터 도입된 클래스이며, Optional로 객체를 감싸서 사용한다면 null 체크를 직접하지 않아도 된다.
- null을 다룰 때 발생하는 NullPointerException을 방지하며, 명시적으로 해당 변수가 null 일 수 있다는 가능성을 표현할 수 있다.
사용법
Optional 을 사용하는 방법에는 크게 Optional 변수 선언하기, Optional 객체 생성하기, Optional 내에 있는 객체 접근 을 이야기 할 수 있다.
Optional 변수 선언하기
나는 공부하면 만들어보는 프로젝트에서 Optional 을 처음 사용해보았다.
// List<ProductEntity> 타입의 객체를 감쌀 수 있는 Optional 타입의 변수
Optional<List<ProductEntity>> productEntities
하지만 지금 productEntities 변수명은 현 상태로도 문제가 없지만, 좀더 의미있는 변수명으로 개선이 가능하다.
// List<ProductEntity> 타입의 객체를 감쌀 수 있는 Optional 타입의 변수
Optional<List<ProductEntity>> optProductEntities // Optional 타입임을 표현
Optional<List<ProductEntity>> maybeProductEntities // Optional 타입임을 표현
변수명은 그냥 클래스 이름을 사용하기도 하지만 “maybe”나 “opt”와 같은 접두어를 붙여서 Optional 타입의 변수라는 것을 좀 더 명확히 나타내기도 한다고 한다.
Optional 객체 생성하기
Optional 클래스는 Optional 객체 생성을 위해 3가지의 정적 팩토리 메서드를 제공한다.
- Optional.empty()
- Optional.of()
- Optional.ofNullable()
Optional.empty()
- null을 담고 있는, 한 마디로 비어있는 Optional 객체를 가져온다.
- 이 객체는 Optional 내부적으로 미리 생성해놓은 싱글턴 인스턴스 이다.
Optional.of()
- null이 아닌 객체를 담고 있는 Optional 객체를 생성한다.
- null이 넘어올 경우, NPE를 던지기 때문에 주의해야 한다.
Optional.ofNullable()
- null인지 아닌지 확신할 수 없는 객체를 담고 있는 Optional 객체를 생성한다.
- Optional.empty()와 Optional.ofNullable(value)를 합쳐놓은 메소드라고 생각하면 쉽다.
- null이 넘어올 경우, NPE를 던지지 않고 Optional.empty()와 동일하게 비어 있는 Optional 객체를 얻어온다.
- 해당 객체가 null인지 아닌지 자신이 없는 상황에서는 이 메소드를 사용해야 한다.
Optional 이 담고있는 객체 접근하기
Optional 클래스는 담고 있는 객체를 꺼내오기 위해서 다양한 인스턴스 메소드를 제공한다. Optional이 담고 있는 객체가 존재할 경우 해당 값을 반환하나, Optional이 비어있는 경우(즉, null을 담고 있는 경우), 다르게 동작한다. 따라서 비어있는 Optional에 대해서 다르게 작동하는 부분만 이해한다면 Optional 을 사용할 수 있다.(Optional 이 비어있는 경우를 정리한다.)
get()
- 비어있는 Optional 객체에 대해서, NoSuchElementException을 던진다.
- .get() 은 값이 항상 존재함을 확신할 경우에만 사용한다.
- 안전하게 사용하기 위해서 isPresent() 메서드를 함께 활용하면 좋다.
orElse(T other)
- 값이 존재하지 않을 경우, 주어진 값(넘겨진 인자)를 반환한다.
orElseGet(Supplier<? extends T> other)
- 비어있는 Optional 객체에 대해서, 넘어온 함수형 인자를 통해 생성된 객체를 반환한다.
- 비어 있는 경우에만 함수가 호출되어 불필요한 계산을 피할 수 있다.(orElse(T other) 메서드보다 성능적으로 이점을 기대할 수 있다.)
orElseThrow(Supplier<? extends X> exceptionSupplier)
- 비어있는 Optional 객체에 대하여, 넘겨준 함수형 인자를 통해 예외를 발생시킨다.
참고 링크