Optional

hoon·2025년 1월 23일

JAVA

목록 보기
15/21

Java의 Optional 클래스는 Java 8에서 추가된 클래스 중 하나로, null 처리를 보다 명시적으로 하고, NullPointerException(NPE) 문제를 방지하기 위해 도입되었다. Optional은 값이 있을 수도 있고 없을 수도 있는 상황을 나타내는 컨테이너 객체로 사용된다.


1. Optional의 주요 목적

  • 명시적으로 null을 처리하도록 강제한다.
  • NullPointerException을 예방한다.
  • 메서드에서 null*을 반환하는 대신 값이 있거나 없는 상태**를 표현할 수 있다.
  • 코드를 더 읽기 쉽고 안전하게 만든다.

2. Optional 생성 방법

Optional 객체는 여러 가지 방법으로 생성할 수 있다.

2.1 empty()

Optional 객체를 생성한다.

Optional<String> emptyOptional = Optional.empty();

2.2 of()

값이 반드시 있어야 할 때 사용한다. 값이 null이면 NullPointerException이 발생한다.

Optional<String> optional = Optional.of("Hello");

2.3 ofNullable()

값이 있을 수도 있고 없을 수도 있는 경우 사용한다. 값이 null이면 빈 Optional 객체를 반환한다.

Optional<String> optional = Optional.ofNullable(null); // 빈 Optional
Optional<String> optional2 = Optional.ofNullable("Hello"); // 값이 있는 Optional

3. Optional의 주요 메서드

Optional 클래스는 값을 안전하게 다룰 수 있도록 다양한 메서드를 제공한다.

3.1 isPresent() / isEmpty()

  • isPresent(): 값이 존재하면 true, 없으면 false를 반환한다.
  • isEmpty(): 값이 없으면 true, 있으면 false를 반환한다.
Optional<String> optional = Optional.ofNullable("Hello");
System.out.println(optional.isPresent()); // true
System.out.println(optional.isEmpty());  // false

3.2 get()

Optional에 값이 존재하면 값을 반환한다. 값이 없으면 예외를 발생시킨다.

Optional<String> optional = Optional.of("Hello");
System.out.println(optional.get()); // Hello

⚠️ 주의: 값이 없는 경우 NoSuchElementException이 발생하므로, 사용 시 isPresent()로 값이 있는지 확인해야 한다.

3.3 orElse()

값이 존재하면 해당 값을 반환하고, 없으면 기본값을 반환한다.

Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.orElse("Default")); // Default

3.4 orElseGet()

값이 없을 때 실행할 동작을 람다식으로 정의할 수 있다.

Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.orElseGet(() -> "Generated Value")); // Generated Value

3.5 orElseThrow()

값이 없으면 지정된 예외를 발생시킨다.

Optional<String> optional = Optional.ofNullable(null);
optional.orElseThrow(() -> new IllegalArgumentException("Value not found!"));

3.6 ifPresent()

값이 존재하면 특정 동작을 실행한다.

Optional<String> optional = Optional.of("Hello");
optional.ifPresent(value -> System.out.println("Value: " + value)); // Value: Hello

3.7 map()

값이 존재하면 값을 변환하고, 빈 Optional 객체는 그대로 반환한다.

Optional<String> optional = Optional.of("Hello");
Optional<Integer> length = optional.map(String::length);
System.out.println(length.get()); // 5

3.8 flatMap()

map()과 유사하지만, 반환 값이 이미 Optional인 경우에 중첩을 방지한다.

Optional<String> optional = Optional.of("Hello");
Optional<String> upper = optional.flatMap(value -> Optional.of(value.toUpperCase()));
System.out.println(upper.get()); // HELLO

4. 실제 사용 사례

4.1 메서드 반환값으로 사용

기존 방식:

public String findName() {
    return null; // 값이 없으면 null 반환
}

Optional 방식:

public Optional<String> findName() {
    return Optional.ofNullable(null); // 값이 없으면 Optional.empty()
}

4.2 안전한 값 처리

Optional<String> name = findName();
String result = name.orElse("Unknown");
System.out.println(result);

4.3 값이 있을 때만 처리

findName().ifPresent(name -> System.out.println("Name: " + name));

5. Optional 사용 시 주의점

  1. 필드에 사용하지 않는다.
    • Optional은 반환값이나 로직 처리에 사용하며, 클래스의 필드로 사용하면 불필요한 복잡성을 초래한다.
  2. get()을 남용하지 않는다.
    • get()은 값이 없는 경우 예외를 발생시키므로 orElse(), orElseGet(), 또는 ifPresent()를 사용하는 것이 더 안전하다.
  3. Optional은 성능 문제를 고려해야 한다.
    • Optional은 객체이기 때문에 기본 타입(예: int, double)과 비교했을 때 오버헤드가 있을 수 있다. 기본 타입에는 OptionalInt, OptionalDouble 등을 사용한다.

6. 정리

  • Optionalnull 대신 사용하여 안전하게 값을 다룰 수 있는 도구다.
  • 값이 있는 경우와 없는 경우를 명시적으로 처리할 수 있어 코드의 가독성과 안정성을 높인다.
  • 하지만 모든 상황에서 Optional을 사용하는 것은 적합하지 않으므로, 상황에 맞게 사용하는 것이 중요하다.

0개의 댓글