반응형

📝Optional

개발할 때 가장 많이 발생하는 예외중 하나는 NPE로서 NPE를 피하려면 null 여부 검사를 해야하는데 코드가 복잡하고 번거롭다 Java8에서 나온 Optional<T> 클래스를 이용해 NPE를 방지할 수 있도록 도와준다.

 

  • 참고로 자바스크립트에서는 Optional사용시 null이나 undefinedundefined를 반환시킨다 [Null에 대한 에러 발생 핸들링]

 

 

Optional 사용해보기

package hello.exception;

import java.util.Optional;

public class Main {
    public static void main(String[] args) throws Exception{

        /** ---- optional 값 체크 ---- **/
        Optional<String> optVal0 = Optional.of("abc");
        Optional<String> optVal2 = Optional.ofNullable(null); // Null 체크 NPE 발생 X
        // Optional<String> optVal1 = Optional.of(null);      // NullPointerException 발생

        System.out.println(optVal2);
        // hello 값이 있는 경우 : Optional[hello]
        // null인 경우         : Optional.empty

        /** ---- optional 초기화 ---- **/
        Optional<String> optVal3 = null;             // 사용 금지!!
        Optional<String> optVal4 = Optional.empty(); // 정상 초기화 작업

        /** ---- optional 값 체크해서 Null 핸들링 하기 ---- **/
        Optional<String> optVal = Optional.ofNullable("test");
        String str1 = optVal.get();                                  // optVal에 저장된 값 반환, Null이면 예외 발생
        String str2 = optVal.orElse("");                             // optVal에 저장된 값 반환, Null이면 orElse안에 값 반환    [많이 사용] | 매개변수 : T
        String str3 = optVal.orElseGet(()->"");                      // optVal에 저장된 값 반환, Null이면 orElseGet안에 값 반환 [많이 사용] | 매개변수 : Supplier
        String str4 = optVal.orElseThrow(NullPointerException::new); // null이면 false, 아니면 true를 반환

        // ifPresent -> null이 아닐 때만 수행한다
        Optional.ofNullable("notNull").ifPresent(System.out::println);

    }

}

Optional이라는게 NPE를 체크하기 위해서 사용하는데 Optional.of의 경우 이미 null이 아니라는 걸 알고 있어야 쓸 수 있기 때문에 Optional.ofNullable을 사용합니다.

 

  • Optional.of
    • null이 아닌 값을 감싸는 Optional 객체를 생성합니다. 인자가 null이면 NullPointerException을 던집니다.
  • Optional.ofNullable
    • 값이 null일 수 있는 경우 사용합니다. 값이 null이면 빈 Optional 객체를 반환합니다.
  • Optional.empty()
    • 빈 Optional을 반환합니다. null을 넣는게 아니라 빈 Optional을 넣어서 초기화 시킵니다.
  • orElseThrow
    • null이 아닌 경우는 해당 값을 반환하고 null인 경우 Supplier가 제공하는 예외를 던집니다.
  • ifPresent
    • 값이 존재하면 true, 그렇지 않으면 false를 반환합니다. 만약 ifPresent의 매개변수 값에 함수가 들어간 경우 Null이 아닐 때 실행되게 됩니다.

 

orElse vs orElseGet 

package hello.exception;


import org.junit.jupiter.api.Test;

import java.util.Optional;

public class orElseTest {

    @Test
    public void testOptionalElse(){

        String notNull ="not Null";
        String nulll = null;

        String resultNullOrElse = Optional.of(notNull).orElse(welcome());           // welcome 함수 실행
        String resultNotNullOrElse = Optional.ofNullable(nulll).orElse(welcome());  // welcome 함수 실행

        System.out.println("notNullOrElse : " + resultNullOrElse); // notNullOrElse : not Null
        System.out.println("NullOrElse : " + resultNotNullOrElse); // NullOrElse : WelComeTo Blog

        System.out.println("===============================");

        String resultNullOrElseGet = Optional.of(notNull).orElseGet(this::welcome);           // doesn't call welcome
        String resultNotNullOrElseGet = Optional.ofNullable(nulll).orElseGet(this::welcome);  // welcome 함수 실행

        System.out.println("notNullOrElseGet : " + resultNullOrElseGet); // notNullOrElseGet : not Null
        System.out.println("NullOrElseGet : " + resultNotNullOrElseGet); // NullOrElseGet : WelComeTo Blog

        /**
         * ---- 출력결과
         * welcome!!
         * welcome!!
         * notNullOrElse : not Null
         * NullOrElse : WelComeTo Blog
         * ===============================
         * welcome!!
         * notNullOrElseGet : not Null
         * NullOrElseGet : WelComeTo Blog
         *
         */

    }

    public String welcome(){
        System.out.println("welcome!!");
        return "WelComeTo Blog";
    }
}

null도 아닌데 실행시키는 경우 말고는 orElseGet을 대체적으로 사용합니다.

 

  • orElse
    • (T other)로 값을 받는데 얘는 Eager Evaluation으로 동작하기 때문에 Null이든 말든 orElse의 값이 있으면 실행하게 됩니다.
  • orElseGet
    • Supplier의 get을 이용하는데 Supplier의 get이 Lazy Evaluation으로 동작하기 때문에 결과가 Null 이여야지만 동작하게 됩니다. 그래서 Null인 경우 아예 동작을 하지 않는 것이죠

 

 

🔗 참고 및 출처

https://erjuer.tistory.com/102

반응형