개발/Java

자바 Optional 이란

하프킴 2021. 5. 18. 15:10
728x90

java.util에 속하고, 1.8부터 제공됨. Null 처리를 간편하게 하기 위해서 등장.

T 객체를 포장해주는 래퍼 클래스이고, NullPointerException 예외를 예방할 수 있다.

 

 

public final class Optional<T>

final 로 정의되어 있어 더 이상 확장이 불가능하다.

 

 

Optional의 특이한 점은

아래와 같이 객체를 생성하지 않는다. 

new Optional();

 

 

아래의 3개의 메소드를 통해 Optional 클래스의 객체를 생성할 수 있다.

 

데이터가 없는 Optional 객체를 생성하려면 이와 같이 empty() 메소드를 이용한다. 

 

javadoc에는 아래와 같이 기술되어 있다.

     * Returns an empty {@code Optional} instance.  No value is present for this

 

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

 

만약 null이 추가될 수 있는 상황이면 이 메소드를 사용한다.

javadoc에는 아래와 같이 기술되어 있다.

     * Returns an {@code Optional} describing the given value, if
     * non-{@code null}, otherwise returns an empty {@code Optional}.
     *
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? (Optional<T>) EMPTY
                             : new Optional<>(value);
    }

 

반드시 데이터가 들어갈 수 있는 상황에는 of() 메소드를 사용한다.

javadoc에는 아래와 같이 기술되어 있다.

     * Returns an {@code Optional} describing the given non-{@code null}
     * value.

 

    public static <T> Optional<T> of(T value) {
        return new Optional<>(Objects.requireNonNull(value));
    }

 

아래의 메소드는 데이터를 리턴하는 메소드들이다.

 

 

가장 많이 사용되는메소드이다. 만약 데이터가 없을 경우에는 null이 리턴된다.

 

javadocs에는 아래와 같이 기술되어 있다.

     * If a value is present, returns the value, otherwise throws
     * {@code NoSuchElementException}.
     *
     * @apiNote
     * The preferred alternative to this method is {@link #orElseThrow()}.
     *
     * @return the non-{@code null} value described by this {@code Optional}
     * @throws NoSuchElementException if no value is present
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

 

만약 값이 없을 경우에는 orElse() 메소드를 사용하여 기본값을 지정할 수 있다.

javadocs에는 아래와 같이 기술되어 있다.

     * If a value is present, returns the value, otherwise returns
     * {@code other}.
     *
     * @param other the value to be returned, if no value is present.
     *        May be {@code null}.
     * @return the value, if present, otherwise {@code other}
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }

 

Supplier<T>라는 인터페이스를 활용하는 방법으로 orElseGet()을 사용할 수 있다.

javadocs에는 아래와 같이 기술되어 있다.

     * If a value is present, returns the value, otherwise returns the result
     * produced by the supplying function.
     *
     * @param supplier the supplying function that produces a value to be returned
     * @return the value, if present, otherwise the result produced by the
     *         supplying function
     * @throws NullPointerException if no value is present and the supplying
     *         function is {@code null}
     */
    public T orElseGet(Supplier<? extends T> supplier) {
        return value != null ? value : supplier.get();
    }

 

 

만약 여기에도 데이터가 없을 경우에 예외를 발생시키고 싶으면 orElseThrow() 메소드를 사용한다. 

     * If a value is present, returns the value, otherwise throws
     * {@code NoSuchElementException}.
     *
     * @return the non-{@code null} value described by this {@code Optional}
     * @throws NoSuchElementException if no value is present
     * @since 10
     */

 

 

    public T orElseThrow() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }