빙응의 공부 블로그

[JAVA] Optional 본문

JAVA

[JAVA] Optional

빙응이 2023. 11. 28. 21:43

📝 JAVA 8 Optional 

자바 옵셔널은 자바 8에서 최초로 도입 되었다. 

그 이유는 바로 NULL 때문이다. 프로그래밍을 하다보면 NULL 처리를 필수적으로 하게 된다. 기존에는 NULL 체크를 해서 NULL이 아닌 경우 뒤의 로직으로 넘어가게 분기처리를 하는 형태로 작업을 진행하였다. 이러한 NULL 처리를 하기 위해 

Optional을 사용한다.

 

 

 

📝Optional 이란?

  • 존재할 수도 있지만 안할 수도 있는 객체를 의미한다. NULL이 될 수도 있는 객체를 감싸고 있는 일종의 래퍼 클래스
  • 기존엔 객체를 직접 NULL인지 체크 했지만 Optional에 담아서 쓰면 NULL을 다루기 좋아진다.
void main() {
	House house = houseService.getRandomHouse();
	if (house.getOnwer() != null) {
		System.out.println("onwer: " + house.getOnwer().getName());
	}
	System.out.println("address: " + house.getAddress());
}

위 코드처럼 Optional이 없을 때는 if 문을 이용해서 NULL을 체크 했었다. 

Optional의 효과
  • 명시적으로 해당 변수가 NULL일 수도 있는 가능성을 표현 가능
  • NPE를 유발하는 NULL을 직접 다루지 않아도 된다.
  • NULL 체크를 안해도 된다. 

 

📝Optional 기본 사용방법

Optional 선언
  • 제네릭을 제공하기 때문에, 변수를 선언할 때 작성한 타입 파라미터에 따라서 감쌀 수 있는 객체의 타입이 결정된다.
  • 변수명은 maybe나 opt같은 접두어를 붙여 Optional 타입을 알리기도 한다. (실무)
객체 생성
  • Optional.empty()
    • NULL을 담고 있는 Optional 객체를 얻어온다.
    • 비어있는 객체는 Optional 내부적로 미리 생성해 놓는 싱글턴 인스턴스이다. 
Optional<String> emptyOptional = Optional.empty();
  • Optional.of(value)
    • NULL이 아닌 객체를 담는 Optional 객체를 생성한다.
    • NULL이 넘어올 경우, NPE를 던지기 때문에 주의해야 한다.

 

Optional<String> optionalWithValue = Optional.of(value);

 

  • Optional.ofNullable(value)
    • NULL인지 아닌지 확신할 수 없는 객체를 담고 있다.
    • Optional.empty()와 Optional.of(value)를 합쳐놓은 메소드이다. 
    • NULL이 넘어오면 Optional.of(value)와 다르게 Optional.empty() 와 같은 객체를 던진다.

 

📝Optional 객체 존재 여부 확인

  • Optional은 NULL에 대해 다루기 때문에 NULL인지 아닌지 확인해야하는 메소드가 필요하다.
  • 아래 로직을 통해 존재 여부를 확인하고 후속 진행이 가능하도록 분기 처리를 할 수 있다.
리턴 타입 메소드 용도
boolean isPresent() 객체가 존재한다면 True가 리턴되고 비어있는 경우 false를 리턴한다. 
void ifPresent() 객체가 존재한다면 ( ) 안에 작업을 진행하는 메소드이다.
void  ifPresentOrElse() 객체가 존재할 때와 존재하지 않을 때의 작업을 모두 지정 가능하다. 

 

isPresent 예제
Optional<String> emptyOptional = Optional.empty();

if (!emptyOptional.isPresent()) {
    System.out.println("값이 없습니다.");
}
ifPresent 예제
import java.util.Optional;

public class IfPresentExample {
    public static void main(String[] args) {
        // 값이 있는 Optional
        Optional<String> optStrWithValue = Optional.of("Hello, Optional!");

        // 값이 있는 경우 작업을 수행
        optStrWithValue.ifPresent(value -> {
            System.out.println("값이 있습니다: " + value);
        });

        // 값이 없는 Optional
        Optional<String> optStrWithoutValue = Optional.empty();

        // 값이 없는 경우 작업을 수행하지 않음
        optStrWithoutValue.ifPresent(value -> {
            System.out.println("값이 있습니다: " + value); // 실행되지 않음
        });
    }
}

 

ifPresentOrElse() 예제
Optional<String> optionalValue = Optional.of("Hello, Optional!");

optionalValue.ifPresentOrElse(
    value -> System.out.println("Value is present: " + value),
    () -> System.out.println("Value is absent")
);
// 출력: Value is present: Hello, Optional!

📝Optional 객체 접근

  • Optional 클래스는 담고 있는 개체를 꺼내오기 위해서 다양한 인스턴스 메소드를 제공한다.
  • 아래 메소드 모두 Optional이 담고 있는 개체가 존재할 경우 동일하게 해당 값을 반환하고 비어 있는 경우 작동이 다름
메소드 존재 NULL
get() 제네릭 값을 반환 NoSuchElementException 오류를 던짐
orElse(T other) 제네릭 값을 반환 파라미터로 입력된 인자를 리턴
orElseGet(Supplier<? extends T> other) 제네릭 값을 반환 넘어온 함수형 인자를 통해 생성된 객체를 반환한다.
orElseThrow(exception) 제네릭 값을 반환 넘어온 함수형 인자를 통해 생성된 예외를 반환
     

 

get() 예제
Optional<String> optionalValue = Optional.of("Hello, Optional!");

// 값이 있는 경우
String value = optionalValue.get();
System.out.println(value);  // 출력: Hello, Optional!

// 값이 없는 경우 (주의: 이 경우 예외가 발생)
Optional<String> emptyOptional = Optional.empty();
String emptyValue = emptyOptional.get();  // NoSuchElementException 발생
orElse(T other) 예제
Optional<String> optionalValue = Optional.of("Hello, Optional!");

// 값이 있는 경우
String value = optionalValue.orElse("Default Value");
System.out.println(value);  // 출력: Hello, Optional!

// 값이 없는 경우
Optional<String> emptyOptional = Optional.empty();
String emptyValue = emptyOptional.orElse("Default Value");
System.out.println(emptyValue);  // 출력: Default Value
orElseGet(Supplier<? extends T> other) 예제
Optional<String> optionalValue = Optional.of("Hello, Optional!");

// 값이 있는 경우
String value = optionalValue.orElseGet(() -> generateDefaultValue());
System.out.println(value);  // 출력: Hello, Optional!

// 값이 없는 경우
Optional<String> emptyOptional = Optional.empty();
String emptyValue = emptyOptional.orElseGet(() -> generateDefaultValue());
System.out.println(emptyValue);  // 출력: Default Value

private String generateDefaultValue() {
    return "Default Value";
}
orElseThrow(Exception exception) 예제
Optional<String> optionalValue = Optional.of("Hello, Optional!");

// 값이 있는 경우
String value = optionalValue.orElseThrow(() -> new IllegalStateException("Value not present"));
System.out.println(value);  // 출력: Hello, Optional!

// 값이 없는 경우
Optional<String> emptyOptional = Optional.empty();
String emptyValue = emptyOptional.orElseThrow(() -> new IllegalStateException("Value not present"));
// IllegalStateException 발생

 

 

 

📝마무리

지금까지 자바 Optional에 대해 알아봤다. 확실히 사용하면 가독성이 좋아질 것 같은데

지금까지 하던 방식이랑 다른 느낌이라 익숙해지는데 오래 걸릴 것 같다.

혹시 틀린점 있으면 알려주세요.! 

 

 


✔참조 사이트

 

자바 옵셔널 (Java Optional) :: JDM's Blog

개요 자바 옵셔널Java Optional에 대해 알아보고 자바 8부터 시작해 9, 10까지 추가된 옵셔널 메서드를 소개합니다. Java 8 Optional 자바 옵셔널은 자바 8에서 최초로 도입 되었습니다. 도입이 된 이유는

jdm.kr

 

Optional 제대로 알기, 면접 대비! (+간단 실무 코드 예시)

프로그래밍을 하다보면 null 처리를 필수적으로 하게 된다. 기존에는 null 체크를 해서 Null이 아닌 경우 뒤의 로직으로 넘어가게 분기처리를 하는 형태로 작업을 하게 된다. 이러한 null을 처리하기

developsd.tistory.com