Optional

개발공부기록하기·2024년 6월 3일

java

목록 보기
16/16

Optional

Java8에서 부터 지원한 Optional 클래스를 사용해 NPE(NullPointerException)를 방지할 수 있도록 도와준다. null이 올수 있는 값을 감싸는 Wrapper 클래스로 NPE 발생하지 않도록 도와준다.

public final class Optional<T> {

  // If non-null, the value; if null, indicates no value is present
  private final T value;
   
  ...
}
출처: https://mangkyu.tistory.com/70 [MangKyu's Diary:티스토리]

주요 사용 하는 매서드

Optional.empty()
Optional은 Wrapper 클래스이기 때문에 값이 없을 수도 있는데, 이때는 Optional.empty()로 생성할 수 있다.

public class Main {
    public static void main(String[] args) {
        Optional<String> optional = Optional.empty();

        System.out.println("optional :" + optional); // Optional.empty
        System.out.println("optional.isPresent() :"+optional.isPresent()); // false

    }
}

Optional.of() - 값이 Null이 아닌 경우
null이 절대 아닌 경우에 사용한다. 만약에 null 값이 들어가면 NPE 발생한다.

public class Main {
    public static void main(String[] args) {
        Optional<String> optional = Optional.of("MyName");
        System.out.println("optional : "+optional);
    }
}

Optional.ofNullbale() - 값이 Null일수도, 아닐수도 있는 경우
null이 올수도 있고 아닐수도 있을 경우에 사용 orElse 또는 orElseGet 메소드를 이용해서 값이 없는 경우라도 안전하게 값을 가져올 수 있다.

null 아닐경우
public class Main {
    public static void main(String[] args) {
        Optional<String> optional = Optional.ofNullable(getName());
        String name = optional.orElse("anonymous");

        System.out.println(name);

    }

    public static String getName() {
        return "안녕하세요";
    }
}
  

null일 경우

public class Main {
    public static void main(String[] args) {
        Optional<String> optional = Optional.ofNullable(getName());
        String name = optional.orElse("anonymous");

        System.out.println(name);

    }

    public static String getName() {
        return null;
    }
}

사용법1

public class Main {
    public static void main(String[] args) {
        // Java8 이전
        List<String> names = getNames();
        List<String> tempNames = names != null ? names : List.of("1","2","3","4","5","6","7","8","9");

        for (String name : tempNames) {
        System.out.println(name.toString());
        }
        // Java8 이후
        List<String> nameList = Optional.ofNullable(getNames())
                .orElseGet(() -> List.of("1", "2", "3", "4", "5", "6", "7", "8", "9"));

        for (String name : nameList) {
            System.out.println(name.toString());
        }
    }

    public static List<String> getNames() {
        return List.of("9","8","7","6","5","4","3","2","1","0");
    }
}

사용법2

public String findPostCode() {
    UserVO userVO = getUser();
    if (userVO != null) {
        Address address = user.getAddress();
        if (address != null) {
            String postCode = address.getPostCode();
            if (postCode != null) {
                return postCode;
            }
        }
    }
    return "우편번호 없음";
}


public String findPostCode() {
    // 위의 코드를 Optional로 펼쳐놓으면 아래와 같다.
    Optional<UserVO> userVO = Optional.ofNullable(getUser());
    Optional<Address> address = userVO.map(UserVO::getAddress);
    Optional<String> postCode = address.map(Address::getPostCode);
    String result = postCode.orElse("우편번호 없음");

    // 그리고 위의 코드를 다음과 같이 축약해서 쓸 수 있다.
    String result = user.map(UserVO::getAddress)
        .map(Address::getPostCode)
        .orElse("우편번호 없음");
}
출처: https://mangkyu.tistory.com/70 [MangKyu's Diary:티스토리]

orElse와 orElseGet의 차이

orElse: 파라미터로 값을 받는다.
orElseGet: 파라미터로 함수형 인터페이스(함수)를 받는다.
orElseThrow() : Exception 발생 시킨다

    public T orElse(T other) {
        return value != null ? value : other;
    }

    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;
    }

자료 출처 : https://mangkyu.tistory.com/70

0개의 댓글