Optional

수호천사임다·2024년 10월 17일

자바

목록 보기
12/15

Optional이란 ?

  • Optional 클래스는 Integer나 Double 클래스처럼 'T' 타입의 객체를 포장해 주는 래퍼 클래스이다.
  • Optional 인스턴스는 모든 타입의 참조 변수를 저장할 수 있다.
  • Optional 객체를 사용하면 예상치 못한 NullPointerException 예외를 제공되는 메서드로 간단히 회피할 수 있다.
    즉, 복잡한 조건문 없이도 널(null) 값으로 인해 발생하는 예외를 처리할 수 있다.
public final class Optional<T> {
  private final T value; // 모든 종류의 객체 저장가능, null도 가능
}
  • null을 직접 다루는것은 위험, NullPointerException 발생 가능
  • null체크 if문 필수 코드가 지저분 - 이러 문제를 해결하려고 Optional을 이용하여 간접적으로 다룬다.
import java.util.Optional;

Object result = getResult(); // 반환값 1.null 2.객체
if(result !=null){
    System.out.println(result);
}

Optional 객체를 생성하는 다양한 방법

예시 코드 보기
String str = "abc";
Optional<String> optVal = Optional.of(str);
Optional<String> optVal = Optional.of("abc");
Optional<String> optVal = Optional.of(null); // NullPointerException 발생
Optional<String> optVal = Optional.ofNullable(null); // ok

null 대신 빈 Optional 객체를 사용

import java.util.Optional;

Optional<String> optVal = null; // 널로 초기화. 바람직하지 않음
Optional<String> optVal = Optional.empty(); // 빈 객체로 초기화

Optional 객체의 값 가져오기 - get(), orElse(), orElseGet(), orElseThrow()

import java.util.Optional;

Optional<String> optval = Optional.of("abc");
String str1 = optval.get(); // optVal에 저장된 값을 반환, null이면 예외발생
String str2 = optval.orElse(""); // opVal에 저장된 값이 null일 때는, ""를 반환
String str3 = optval.orElseGet(String::new); // 람다식 사용가능 
String str4 = optval.orElseThrow(NullPointerException::new); // 널이면 예외발생

isPresent() - Optional 객체의 값이 null이면 false, 아니면 true

if(Optional.ofNullable(str).isPresent()) { // if (str!=null)
  System.out.printlnm(str);  
}

Optional의 주요 특징

  1. 값이 있을 수도 있고 없을 수도 있는 객체를 표현.
  2. null 대신 사용하여 더 안전하고 가독성 있는 코드를 작성할 수 있다.
  3. 명시적으로 값이 존재하는지 여부를 확인할 수 있도록 도와준다.

Optional 메서드

메서드설명사용 예시
of(T value)값이 null이 아닐 때 해당 값을 감싸는 Optional 객체를 반환Optional<String> optional = Optional.of("Hello");
ofNullable(T value)값이 null일 수도 있을 때 Optional 객체로 반환, null이면 Optional.empty()Optional<String> optional = Optional.ofNullable(null);
empty()빈 Optional 객체를 반환Optional<String> optional = Optional.empty();
get()Optional 객체의 값을 반환, 값이 없으면 NoSuchElementException 발생String value = optional.get();
isPresent()값이 존재하는지 여부를 반환 (true/false)if (optional.isPresent()) { ... }
ifPresent(Consumer<T>)값이 존재할 때 특정 작업을 수행optional.ifPresent(value -> System.out.println(value));
orElse(T other)값이 존재하면 그 값을, 없으면 기본 값을 반환String value = optional.orElse("default");
orElseGet(Supplier<T>)값이 존재하면 그 값을, 없으면 Supplier가 제공하는 값을 반환String value = optional.orElseGet(() -> "default value");
orElseThrow()값이 없을 경우 예외를 던짐String value = optional.orElseThrow();
orElseThrow(Supplier<X>)값이 없을 경우 지정한 예외를 던짐String value = optional.orElseThrow(IllegalArgumentException::new);

기본 타입의 Optional 클래스

  • 자바에서는 IntStream 클래스와 같이 기본 타입 스트림을 위한 별도의 Optional 클래스를 제공한다.
  • 기본 타입에 대한 Optional 클래스들은 박싱으로 인한 성능 저하를 방지하기 위한 것
  • 대규모 파일을 다룰 때 성능개선을 하고 싶으면 기본 타입 Optional 사용

람다, 스트림이 모든걸 감싸고, 모든걸 객체로 다루기 때문에 성능이 떨어짐
더 높은 성능이 필요할때 기본 타입 Optional을 쓰자

public final class OptionalInt {
  
  private final boolean isPresent; // 값이 저장되어 있으면 true
  private final int value; // int타입의 변수 
}
OptionalInt opt = OptionalInt.of(0);
OptionalInt opt2 = OptionalInt.empty();

System.out.println(opt.isPresent); // true
System.out.println(opt2.isPresent); // false
System.out.println(opt.equalse(opt2)); // false
  • isPresent까지 같아야 opt와 opt2가 일치한다.

이로서 Optional에 대해서 공부를 했다.
null을 직접 다루는 것은 위험하고, null 체크는 필수이기 때문에
if문을 사용하게 된다.
if문을 사용하면 코드가 지저분한다.
직접 다루지말고 간접적으로 다루기 위해 Optional을 사용을 하면 NullPointerException 예방도 할 수 있고
코드를 깔끔하게 해결 할 수 있다.

0개의 댓글