티스토리 뷰
Optional에 관한 블로그 글을 보게 됐는데 내용이 좋아서 따로 블로그에 정리하려고 한다.
원본 글은 아래 reference에 있다.
Optional 이란?
NPE(NUllPointerException)를 피하기 위해서는 null 여부를 검사해야 하는데, null 검사를 해야하는 변수가 많은 경우 코드가 복잡해지고 번거롭다.
그래서 Java에는 null이 올 수 있는 값을 감싸는 Wrapper 클래스인 Optional을 사용하면 참조하더라도 NPE가 발생하지 않게 할 수 있다.
메소드
- Optional.empty()
- 값이 없는 경우에, Optional을 생성하고 싶을 때 사용할 수 있다
- 아래 코드를 보면 Optional.empty()를 해도 static 변수인 EMPTY를 리턴한다. 따라서 여러번 호출해도 1개의 EMPTY를 공유하기 때문에 메모리가 절약된다.
public final class Optional<T> { private static final Optional<?> EMPTY = new Optional<>(); private final T value; public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; } ... }
- Optonal.of()
- 만약 Optional로 생성하려는 값이 절대 null이 아니라면 Optional.of()로 생성할 수 있다. null일 경우에는 NPE가 발생한다
//ok Optional.of("name"); //NPE Optional.of(null); //Optional 내부(requireNonNull이 존재한다) public static <T> Optional<T> of(T value) { return new Optional<>(Objects.requireNonNull(value)); }
- Optional.ofNullable()
- 만약 값이 null이 될 수도 있다면 Optional.ofNullable()을 사용하자
- 이렇게 생성된 Optional 객체에 대해서는 orElse 드을 사용해서 안전하게 값을 가져오면 된다.
- Optional.orElse() vs Optional.orElseGet()
- 둘 다 Optional의 값이 null일 경우 파라미터로 전달된 값을 리턴해준다. 하지만 파라미터 타입이 다르다.
- orElse()
- 파라미터로 값을 받는다
- orElseGet()
- 파라미터로 함수형 인터페이스를 받는다
- 이로 인해 실행 로직이 살짝 다른데 만약 orElse()로 값을 리턴하는 함수 호출 코드를 파라미터로 넘겨줬을 경우에는, Optional의 값과 무관하게 함수를 무조건 호출한다. 따라서 orElse()로 함수를 넘겨주면 해당 함수는 무조건 호출된다고 생각하면 된다.
public void test() { Optional.of("myName") .orElse(getName()); //call getName이 찍힌다. } public String getName() { System.out.println("call getName"); return "name"; }
올바른 사용법
Optional 위험한 이유
- Optional의 값을 ifPresent() 등으로 확인하지 않고 바로 get()으로 사용하다면 NPE가 아닌 NoSuchElementException이 발생한다
- 코드의 가독성을 떨어뜨림
- 추가 비용이 발생한다.
- 시간적 비용(Optional의 값을 확인하고 Optinal을 통해서 값을 가져와야 한다)
- 공간적 비용(Optional을 저장하기 위한 메모리가 추가로 필요하다)
위의 문제들과 더불어 애초에 Optional은 메소드의 반환 타입으로 사용되도록 제한적인 경우로 설계되었다고 한다. 따라서 Optional의 올바른 사용법은 메소드의 반환타입으로만 사용하는 것이라고 한다.
이에 대한 자세한 설명은 아래 참고 사이트에 나와 있다.
reference
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크