프로그래밍 언어/Java

[Java] 자바 Optional 정리

happy_life 2022. 7. 6. 13:49

자바 Optional 정리

 

 

Optional 개요

Optional은 제네릭 클래스로 T타입의 객체를 감싸는 래퍼 클래스이다.  연산의 결과로 Optional 객체를  반환한다. 이 객체 안에 멤버변수로 값을 넣고 사용한다. 이러면 반환된 결과가 null인지를 직접 체크하지 않아도 된다.

 

기존 코드 예제

String str = "abcd";

if (str != null) {
    System.out.println(str);
}

str이 null일 가능성이 있으므로, if문을 통해 체크해주어야 한다. 이런 번거로움을 해결해주는 것이 바로 Optional 클래스이다.

 

Optional 객체 구조

 

동작과정: Optional 객체 안에 멤버변수로 값을 저장해 놓고, 이를 get() 등의 메서드로 가져온다.

 

 

Optional 객체 생성

of()

멤버변수의 값이 null일 가능성이 없는 경우, of()를 사용해 Optional 객체를 생성할 수 있다.

 

코드 예제

String str = "abcd";

// 생성방법 1: of
Optional<String> optionalStr = Optional.of(str);
Optional<String> optionalStr2 = Optional.of("abc");

 

 

ofNullable()

멤버변수의 값이 null일 가능성이 있는 경우, ofNullable()을 사용해 Optional 객체를 생성할 수 있다.

 

코드 예제

String str = "abcd";


 // 생성방법 2: ofNullable(null) - Null일 가능성이 있는 경우 사용
 // Optional<Object> o = Optional.of(null); //nullPointException 발생
 Optional<String> nullOptional = Optional.ofNullable(null); // 바람직 하진 않음

 

하지만 ofNullable(null)과 같은 코드는 바람직 하지 않다. Optional<T> 타입을 기본값으로 초기화할 때는 empty()를 사용한다.

// 기본 값으로 초기화할 때는 empty를 사용
Optional<String> emptyOptional = Optional.empty();

 

 

 

Optional 객체 값 가져오기

get()

Optional 객체에 저장된 멤버변수 값을 가져올 때는 get()을 사용할 수 있다. 값이 null인 경우 Exception이 발생한다. 따라서 잘 사용하지 않는다.

 

코드 예제

Optional<String> optionalStr1 = Optional.of("abc");
System.out.println(optionalStr1.get());

 

 

orElse()

get()과 달리 값이 null인 경우 예외가 발생하지 않고 지정한 값을 반환한다.

 

코드 예제

Optional<String> optionalStr2 = Optional.of("abc");
Optional<String> optionalStr3 = Optional.ofNullable(null);

System.out.println(optionalStr2.orElse("null 입니다")); //abc
System.out.println(optionalStr3.orElse("null 입니다")); //null 입니다

 

 

orElseGet()

orElse()의 변형으로 값을 반환하는 람다식을 지정할 수 있다.

 

코드 예제

//orElseGet()
System.out.println(optionalStr3.orElseGet(() -> "예외"));

매개변수로 Supplier를 받는다. Supplier는 함수형 인터페이스이다. 더 자세한 내용은 이 링크에 정리되어 있다. https://abcdefgh123123.tistory.com/420

 

 

orElseThrow()

null일 때 예외를 던지게 할 수도 있다.

 

코드 예제

//orElseThrow()
try {
    System.out.println(optionalStr3.orElseThrow(() -> new NullPointerException()));
} catch (NullPointerException e) {
    System.out.println("null 입니다.");
}

 

isPresent()

Optional 객체의 값이 null이면 false, 아니면 true를 반환한다.

 

코드 예제

Optional<Object> nullOptional = Optional.ofNullable(null);
Optional<String> stringOptional = Optional.of("123");

//isPresent()
System.out.println(nullOptional.isPresent()); // false
System.out.println(stringOptional.isPresent()); // true

 

 

ifPresent()

값이 있으면 주어진 람다식을 실행하고 없으면 아무것도 하지 않는다.

 

코드 예제 

Optional<Object> nullOptional = Optional.ofNullable(null);
Optional<String> stringOptional = Optional.of("123");

//ifPresent()
nullOptional.ifPresent((i)->System.out.println(i)); //출력X
stringOptional.ifPresent((i)->System.out.println(i));//123

 

 

스트림처럼 사용하는 메서드

스트림처럼 Optional 객체에서 filter(), map(), flatMap()을 사용할 수 있다. 만약 값이 null이면 아무 일도 하지 않는다.

 

코드 예제

Optional<String> s = Optional.of("123");

int integer = s.filter(i -> i.length() > 0)
               .map(Integer::parseInt)
               .orElse(3);
               
System.out.println(integer); //123