Java Optional

MINI·2023년 2월 20일
0

java

목록 보기
1/2

JAVA에서 NULL처리


java에서는 데이터가 없음을 처리하기 위해 null를 사용할때가 있다. 하지만 잘못 사용하면

NullPointerException(NPE)를 발생시킬수 있다. java8에서 부터는 Optional 클래스를 제공한다.

Optional 클래스를 사용하면 null safe하게 개발 할 수 있다.

Optional


Optional 클래스는 값이 존재할 수도 있고, 존재하지 않을 수도 있는 객체를 명시할때 사용한다.

다음은 Optional 클래스 구현 코드중 일부이다.

public final class Optional<T> {

		private static final Optional<?> EMPTY = new Optional<>(); 
   
    private final T value;

    private Optional() {
        this.value = null;
    }  
 
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
    public boolean isPresent() {
        return value != null;
    } 
    public T orElseGet(Supplier<? extends T> supplier) {
        return value != null ? value : supplier.get();
    }
    public T orElseThrow() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }
}

위 코드를 분석해보면 몇 가지 특징을 알 수 있다.

  1. Optional 클래스는 제네릭으로 구현되어 있습니다. T는 포함된 값의 타입을 나타낸다.
  2. 위 코드에서 보면 Optional은 final로 선언되어있는 불변객체이다. 따라서 한번 선언하면 변경이 불가능하다.
  3. 값이 없는 데이터는 empty() 값이 있는 데이터는 of() 메서드를 사용하여 객체를 생성한다.
  4. orElse(),orElseGet(),orElseThrow(),isPresent()같은 메서드로 null값을 안전하게 처리한다.

Optional 사용법


Optional 객체 생성

Optional 클래스를 생성할 때는 해당 유형의 객체를 전달해야 한다.

Optional 클래스를 생성할 때는 3가지 방법을 사용 할 수 있다.

  1. Optional.empty()

값이 없는 Optional 객체를 생성한다.

Optional<String> emptyExample = Optional.empty();
  1. Optional.of(T value)

값이 있는 Optional 객체를 생성한다. 이 때, 전달된 값이 null이면 NullPointerException이 발생한다.

Optional<String> ofExample = Optional.of("ofExample ");
  1. Optional.ofNullable(T value)

값이 있는 Optional 객체를 생성한다. 이 때, 전달된 값이 null이면 빈 Optional 객체가 생성된다.

String nullValue = null;
Optional<String> ofNullableExample= Optional.ofNullable(value);

Optional 메소드 사용

  1. get()

Optional 객체가 값을 포함하고 있으면 값을 반환합니다. 그렇지 않으면 NoSuchElementException을 발생시킨다.

Optional<String> ofExample = Optional.of("ofExample ");
String value = ofExample .get();
  1. isPresent()

Optional 객체가 값을 포함하고 있는지 여부를 반환한다.

Optional<String> isPresentExample= Optional.of("isPresent");
if (isPresentExample.isPresent()) {
    System.out.println("Value is present.");
}
  1. orElse(T other)

Optional 객체가 값을 포함하고 있으면 값을 반환하고, 그렇지 않으면 인수로 전달된 값을 반환한다.

Optional<String> orElseExample= Optional.empty();
String value = orElseExample.orElse("Default Value");
  1. orElseGet(Supplier<? extends T> other)

Optional 객체가 값을 포함하고 있으면 값을 반환하고, 그렇지 않으면 Supplier 객체의 get() 메서드가 반환하는 값을 반환한다.

Optional<String> optionalString = Optional.empty();
String value = optionalString.orElseGet(() -> "Default Value");
  1. orElseThrow(Supplier<? extends X> exceptionSupplier)

Optional 객체가 값을 포함하고있으면 값을 반환하고,그렇지 않으면 NoSuchElementException또는 직접 설정한 Exception을 반환 한다.

Optional<String> orElseThrowExample= Optional.empty();
String value = orElseThrowExample.orElseThrow(() -> new CustomException("Value not present"));

Supplier


Supplier는 자바 함수형 인터페이스(Functional Interface) 중 하나로, 매개변수가 없는 메서드를 가지며, T 타입의 객체를 반환하는 메서드를 나타낸다.

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Supplier 인터페이스는 get() 메서드 하나만을 추상 메서드로 가지고 있으며, 이 메서드는 T 타입의 객체를 반환한다. 이 인터페이스는 매개변수가 없는 상황에서 T 타입의 값을 리턴하는 용도로 사용 된다.

Optional 에서 Supplier

Optional<String> optional = Optional.empty();
String value = optional.orElseGet(() -> "Default Value");

위 코드에서는 Optional 객체가 값이 없기 때문에, orElseGet() 메서드가 Supplier 인터페이스의 get() 메서드를 호출한다. 이때 선언된 람다 함수에 의해 "Default Value" 값을 반환하고 T타입에 문자열 타입이 저장된다.

profile
느리지만 꾸준히

0개의 댓글