Optional Class Example


Reference : http://javaiyagi.tistory.com/443
http://multifrontgarden.tistory.com/128
http://asfirstalways.tistory.com/354

Optional Class In Java 8

=> 하스켈, 스칼라 등의 함수형 언어에서 사용되고 있는 '선택형 값' 개념의 영향을 받아 Optional<T>라는 새로운 클래스를 제공한다.
=> 값이 없는 상황을 모델링 하는 것

  1. Optional은 선택형 값을 캡슐화 하는 클래스이다. 값이 존재하면 그 값을 감싼다.
  2. 값이 없는 경우에는 Optional.empty() 메서드로 Optional을 반환한다.
  3. empty 메서드는 Optional의 싱글턴 인스턴스를 반환하는 정적 팩토리 메서드이다.
null vs Optional.empty()

- null을 참조하면 NPE 발생!
- empty 메서드의 반환 값은 Optional이라는 객체 !

어떻게 사용할 것인가?

잠재적으로 null이 될 수 있는 대상을 Optional로 감싼다.

// java 8 이전 code
Object value = map.get("key");

// java 8 code
Optional<Object> value = Optional.ofNullable(map.get("key"));

In General

public class Computer {
    private Soundcard soundcard;
    public Soundcard getSoundcard() {...}
    ...
}

public class Soundcard {
    private USB usb;
    public USB getUSB() {...}
}

public class USB{
    public String getVersion() {...}
}
String version = computer.getSoundcard().getUSB().getVersion();

# Enable: NullPointerException
String version = "UNKNOWN";

// Deep Doubt (깊은 의심) 패턴
if (computer != null) {
    Soundcard soundcard = computer.getSoundcard();
    if (soundcard != null) {
        USB usb = soundcard.getUSB();
        if (usb != null) {
            version = usb.getVersion();
        }
    }
}

// 같은 코드
if (computer != null 
    && computer.getSoundcar() != null 
    && computer.getSoundcar().getUSB() != null)
    version = computer.getSoundcard().getUSB().getVersion();

In Optional class

Optional API

  • void ifPresent(Consumer<T>)
  • Optional<T> filter(Predicate<T>)
  • Optional<U> map(Function<T, U>)
  • T get()
  • T orElse()
  • TorElseGet(Supplier<T>)
  • TorElseThrow(Supplier<U>)
public class Computer {
    private Optional<Soundcard> soundcard;
    public Optional<Soundcard> getSoundcard() {...}
    ...
}

public class Soundcard {
    private Optional<USB> usb;
    public Optional<USB> getUSB() {...}
}

public class USB {
    public String getVersion() {...}
}
String name = computer.flatMap(Computer::getSoundcard)
        .flatMap(Soundcard::getUSB)
        .map(USB::getVersion)
        .orElse("UNKNONW");

General vs Optional

// general
Soundcard soundcard = ...;
if (soundcard != null)
    System.out.println(soundcard);

// optional
Optional<Soundcard> soundcard = ...;
soundcard.ifPresent(System.out::println);
// general
Soundcard soundcard = maybeSoundcard != null ? maybeSoundcard : new Soundcard("basic_soundcard");

// optional
Soundcard soundcard = maybeSoundcard.orElse(new Soundcard("basic_sound_card"));
// general
USB usb = ...;
if (usb != null && "3.0".equals(usb.getVersion()))
    System.out.println("ok");

// optional
Optional<USB> maybeUSB = ...;
maybeUSB.filter(usb-> "3.0".equals(usb.getVersion())
    .ifPresent(() -> System.out.println("ok"));

results matching ""

    No results matching ""