어제 오늘 내일

[Java] Optional 사용법 (NullPointerException 방지) 본문

IT/Java

[Java] Optional 사용법 (NullPointerException 방지)

hi.anna 2026. 1. 2. 08:15

Java의 Optional은 값이 있을 수도 있고 없을 수도 있는 객체를 표현하는 래퍼(wrapper) 클래스입니다.
주로 NullPointerException을 방지하고, null 체크를 더 안전하고 명확하게 처리하기 위해 사용됩니다.

Optional은 Java 8부터 도입되었으며, “null 대신 사용할 수 있는 타입”이라고 이해하면 쉽습니다.

 

1. Optional 기본 생성

1-1. 값이 있는 Optional 생성

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

주의: of(null)은 예외 발생 → 값이 null일 가능성이 없다면 이 방식 사용.

1-2. 값이 null일 수도 있는 경우

Optional<String> opt = Optional.ofNullable(str);

특징: str이 null이면 빈 Optional 생성.

1-3. 빈 Optional 생성

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

 

 

2. Optional 값 꺼내기

2-1. get() 사용 (권장 X)

String value = opt.get(); // 값이 없으면 NoSuchElementException

get()은 값이 무조건 있다고 가정하므로 위험 → 가급적 사용을 지양.

2-2. orElse() – 값이 없으면 기본값 반환

String result = opt.orElse("기본값");

2-3. orElseGet() – 지연 계산 (Supplier 사용)

String result = opt.orElseGet(() -> "계산된 기본값");

orElse()는 무조건 실행되지만, orElseGet()은 Optional이 비었을 때만 실행됨.

2-4. orElseThrow() – 값이 없으면 예외 던짐

String result = opt.orElseThrow(() -> new IllegalArgumentException("값 없음"));

 

 

3. 값이 있는지 확인하기

3-1. isPresent()

if (opt.isPresent()) {
    System.out.println(opt.get());
}

3-2. isEmpty() (Java 11+)

if (opt.isEmpty()) {
    System.out.println("값 없음");
}

하지만 Optional은 조건문보다는 함수형 스타일을 권장합니다.

 

4. ifPresent() – 값이 있을 때만 실행

opt.ifPresent(value -> System.out.println("값: " + value));

설명

  • null 체크 + 실행을 간결하게 처리

 

5. map() – Optional 내부 값 변환

Optional<String> opt = Optional.of("hello");
Optional<String> upper = opt.map(v -> v.toUpperCase());

upper.ifPresent(System.out::println); // HELLO

장점

map()을 사용하면 null 여부를 직접 확인할 필요 없이 안전한 변환 가능.

 

6. flatMap() – Optional 중첩 제거

예: Optional 안에 Optional이 들어가는 상황에서 사용.

Optional<User> user = Optional.of(new User("Tom"));
Optional<String> name = user.flatMap(u -> u.getNameOptional());

 

 

7. filter() – 특정 조건에 맞는 값만 유지

Optional<Integer> opt = Optional.of(10);

opt.filter(v -> v > 5)
   .ifPresent(System.out::println); // 10

opt.filter(v -> v > 20)
   .ifPresent(System.out::println); // 실행 안됨

 

 

8. Optional 사용이 적합한 상황

✔ NullPointerException 방지

✔ 메서드 반환값이 "없음"을 표현하고 싶을 때

예:

public Optional<User> findUser(String id) {
    if (id.equals("admin")) return Optional.of(new User("admin"));
    return Optional.empty();
}

✔ if-else null 체크를 깔끔하게 하고 싶을 때

여러 null 체크를 함수형 스타일로 간단하게 표현 가능.

 

9. Optional을 남용하면 안 되는 경우

Optional도 객체이므로 불필요하게 사용하면 오히려 성능과 가독성을 해칠 수 있습니다.

  • 필드에 Optional 사용 ❌
  • 메서드 파라미터로 Optional 사용 ❌
  • 단순 내부 처리에 Optional을 남발 ❌

Optional은 주로 반환 타입으로 사용하는 것이 가장 이상적입니다.

 

10. 전체 예제

public Optional<String> getName(boolean exist) {
    if (exist) return Optional.of("Tom");
    return Optional.empty();
}

public void printName() {
    Optional<String> name = getName(false);

    String result = name
        .map(v -> "이름: " + v)
        .orElse("이름이 존재하지 않습니다.");

    System.out.println(result);
}

출력:

이름이 존재하지 않습니다.

안전하게 null을 처리하면서 코드가 깔끔해졌습니다.

 

11. 정리

  • Optional은 null을 안전하게 다루기 위한 wrapper 클래스
  • of(), ofNullable(), empty() 등으로 생성
  • orElse(), orElseGet(), orElseThrow()로 값 처리
  • map(), flatMap(), filter()로 함수형 스타일 제공
  • 주로 메서드 반환 타입으로 사용하여 NullPointerException 방지

 

 

반응형
Comments