[Java] NPE | Optional

Jeini·2025년 9월 24일
0

☕️  Java

목록 보기
63/70
post-thumbnail

❗️ NPE(Null Point Exception) 어려움

  • Java에서 가장 흔한 에러 중 하나이다.
  • 객체가 없는데 (null인데) 그 객체의 메서드나 필드를 호출하려고 하면 발생한다.
  • Java 참조형은 모두 Null 로 초기화
    👉 null 로 된 값 메소드나 필드 참조 시 NPE 발생!

1️⃣ 객체 참조가 null인 경우

String name = null;
System.out.println(name.length()); // ❌ NPE 발생

2️⃣ 배열의 요소가 null인 경우

String[] array = new String[3];
System.out.println(array[0].length());// ❌ NPE 발생

💡 NPE 직접 처리하기

1️⃣ catch문 사용자정의 예외 던짐

// 사용자 정의 예외
public class MyCustomException extends Exception {
    public MyCustomException(String message) {
        super(message);
    }
}
public class Example {
    public static void main(String[] args) throws MyCustomException {
        try {
            String name = null;
            System.out.println(name.length()); // ❌ NPE 발생
        } catch (NullPointerException e) {
            // 기본 NPE 대신 내가 만든 예외 던지기
            throw new MyCustomException("이름이 null입니다!");
        }
    }
}

2️⃣ catch문 기본값 사용

public class Example {
    public static void main(String[] args) {
        String name = null;
        int length;

        try {
            length = name.length(); // ❌ NPE 발생
        } catch (NullPointerException e) {
            System.out.println("null 발견 → 기본값 0으로 처리");
            length = 0; // 기본값 사용
        }

        System.out.println("이름 길이 = " + length);
    }
}

💡 Optional

null 방지 메소드를 지원하는 Wrapper 클래스

  • Optional<T>“값이 있을 수도 있고, 없을 수도 있다”를 표현하는 래퍼(wrapper) 클래스이다.
  • 즉, null 을 직접 쓰지 않고 → 빈 Optional로 표현.
  • 덕분에 NPE 위험이 줄어들고, 호출하는 쪽에서 “값이 없을 때 어떻게 처리할지”를 강제로 고민하게 만들어준다.
Optional<String> opt1 = Optional.of("Hello");       // 절대 null 아님
Optional<String> opt2 = Optional.ofNullable(null);  // null 가능
Optional<String> opt3 = Optional.empty();           // 빈 Optional

✨ Optional 기본 사용법

1️⃣ Optional.of(value)

  • null 이 아닌 값만 감쌀 수 있음.
  • 만약 null 을 넣으면 → NullPointerException 발생.
Optional<String> opt1 = Optional.of("Hello"); // ✅ 정상
Optional<String> opt2 = Optional.of(null);    // ❌ NPE 터짐

👉 보통 절대 null이 아닌 값을 확신할 때 사용한다.

2️⃣ Optional.ofNullable(value)

  • 값이 null 일 수도 있고 아닐 수도 있음.
  • null 이면 → Optional.empty() 를 만들어줌.
Optional<String> opt1 = Optional.ofNullable("Hello"); // ✅ 값 있음
Optional<String> opt2 = Optional.ofNullable(null);    // ✅ 빈 Optional

👉 보통 null이 들어올 수도 있는 상황에서 안전하게 쓰는 게 좋아.

🌟 차이 정리

메서드null 허용 여부null 넣으면
of()❌ (null 불가)NullPointerException 발생
ofNullable()✅ (null 허용)Optional.empty() 반환

3️⃣ orElseThrow()

  • 값이 있으면 → 그 값 반환
  • 값이 없으면 → 예외 던짐
Optional<String> opt = Optional.ofNullable(null);

String value = opt.orElseThrow(() -> new IllegalArgumentException("값이 없어요!"));


✅ 결과 → IllegalArgumentException: 값이 없어요!

👉 반드시 값이 있어야 하는 상황에서 사용해.
(없으면 예외로 강하게 알려줌)

4️⃣ orElseGet()

  • 값이 있으면 → 그 값 반환
  • 값이 없으면 → Supplier (람다식) 실행해서 기본값 생성
Optional<String> opt = Optional.ofNullable(null);

String value = opt.orElseGet(() -> "기본값");
System.out.println(value); // "기본값"

👉 없으면 대체 값 쓰고 싶을 때 사용해.

⚠️ orElse() vs orElseGet() 차이

둘 다 기본값을 쓸 수 있는데, 실행 시점이 다름.

String defaultValue() {
    System.out.println("기본값 생성됨!");
    return "Default";
}

String str1 = Optional.ofNullable("Hello").orElse(defaultValue());
String str2 = Optional.ofNullable("Hello").orElseGet(() -> defaultValue());


✅ 결과

기본값 생성됨!   ← orElse는 값이 있어도 기본값 함수 실행
  • orElse() → 값이 있든 없든 무조건 기본값 계산 실행
  • orElseGet() → 값이 없을 때만 기본값 실행

👉 그래서 기본값 계산 비용이 크면 orElseGet() 이 효율적임.

🌟 차이 정리

메서드값 있음값 없음
orElseThrow(ex)값 반환예외 던짐
orElseGet(supplier)값 반환supplier 실행 → 기본값 반환
orElse(default)값 반환기본값 반환 (항상 실행됨)
profile
Fill in my own colorful colors🎨

0개의 댓글