아빠는 개발자

[java] Exception 처리 본문

Java

[java] Exception 처리

father6019 2025. 2. 25. 10:35
728x90
반응형

 

🎯 1. 예외 처리 방법

try-catch 문

  • try 블록 안에서 예외가 발생할 수 있는 코드를 작성
  • catch 블록에서 예외를 처리
try {
    int result = 10 / 0; // ❌ ArithmeticException 발생
    System.out.println("Result: " + result);
} catch (ArithmeticException e) {
    System.out.println("⚠️ 예외 발생: " + e.getMessage());
}

 

 

 

try-catch-finally 문

  • finally 블록은 예외 발생 여부와 관계없이 무조건 실행
  • 주로 리소스 해제 (예: DB 연결 종료, 파일 닫기) 시 사용
try {
    String text = null;
    System.out.println(text.length()); // ❌ NullPointerException 발생
} catch (NullPointerException e) {
    System.out.println("⚡ NullPointerException 처리됨: " + e.getMessage());
} finally {
    System.out.println("✅ finally 블록 실행 (리소스 해제 등)");
}

 

 

다중 catch 블록

  • 여러 종류의 예외를 각각 처리할 수 있음
  • Java 7 이상에서는 | 기호를 사용하여 여러 예외를 하나의 catch 블록에서 처리 가능

 

try {
    String[] arr = new String[2];
    System.out.println(arr[5]); // ❌ ArrayIndexOutOfBoundsException 발생
} catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
    System.out.println("❗ 예외 발생: " + e.getClass().getSimpleName());
}

 

throws 키워드 (예외 던지기)

  • 메서드에서 예외가 발생할 수 있음을 호출자에게 알림
  • try-catch 대신 메서드 시그니처에 throws 사용
public static void riskyMethod() throws Exception {
    throw new Exception("⚡ 강제로 예외 발생");
}

public static void main(String[] args) {
    try {
        riskyMethod();
    } catch (Exception e) {
        System.out.println("🔥 예외 처리됨: " + e.getMessage());
    }
}

 

 

 

커스텀 예외 만들기 (사용자 정의 Exception)

  • 특정 비즈니스 로직에 맞춘 자체 예외 클래스 생성
  • Exception 또는 RuntimeException을 상속

 

// 🎨 커스텀 예외 정의
public class CustomApiException extends Exception {
    public CustomApiException(String message) {
        super(message);
    }
}

// 💡 커스텀 예외 사용
public static void callApi(String url) throws CustomApiException {
    if (url == null || url.isEmpty()) {
        throw new CustomApiException("❌ URL이 비어 있습니다.");
    }
    System.out.println("🌐 API 호출: " + url);
}

public static void main(String[] args) {
    try {
        callApi(""); // 빈 URL로 예외 발생
    } catch (CustomApiException e) {
        System.out.println("⚡ 커스텀 예외 처리됨: " + e.getMessage());
    }
}

 

 

 

 

🔥 2. Checked vs Unchecked Exception 차이

분류 예시 특징 처리방법
Checked Exception IOException, SQLException 컴파일 시점에 반드시 처리 (try-catch 또는 throws) 필요 try-catch 또는 throws
Unchecked Exception NullPointerException, ArithmeticException 런타임 시점에 발생, 컴파일 시 강제 처리 불필요 선택적 처리 (권장)

 

 

 

🚀 3. 예외 전환 (Wrapping)

  • 하위 레이어에서 발생한 예외를 상위 레이어에 맞는 의미 있는 예외로 전환
  • Spring 프레임워크에서도 비즈니스 예외 전환에 사용
public static void databaseCall() throws Exception {
    throw new IOException("DB 연결 실패");
}

public static void serviceLayer() throws Exception {
    try {
        databaseCall();
    } catch (IOException e) {
        throw new RuntimeException("💥 서비스 예외: DB 연결 문제", e); // 예외 전환
    }
}

public static void main(String[] args) {
    try {
        serviceLayer();
    } catch (RuntimeException e) {
        System.out.println("🔥 최종 처리됨: " + e.getMessage());
        e.printStackTrace();
    }
}

 

 

🌟 4. Spring Framework에서의 예외 처리

@ControllerAdvice & @ExceptionHandler

  • 전역 예외 처리용 클래스 작성 가능
  • Spring MVC에서 API 응답에 적합한 예외 처리 구현
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleGlobalException(Exception e) {
        return "🚨 서버 에러 발생: " + e.getMessage();
    }
}

 

 

 

 

베스트 프랙티스 (Best Practices)

1️⃣ 구체적인 예외를 먼저 처리
2️⃣ catch 블록에서 불필요한 로직 최소화
3️⃣ 로깅 시 스택 트레이스를 포함 (logger.error("에러 발생", e);)
4️⃣ 필요 시 사용자 정의 예외 생성
5️⃣ Exception 대신 구체적 예외 또는 RuntimeException 사용

 

 

 

 

 

 

요약

  • ✅ try-catch-finally를 사용하여 예외 발생 시 정상 흐름 유지
  • ✅ throws로 호출자에게 예외 처리 책임 위임
  • Checked 예외는 컴파일 타임에 처리 강제
  • Unchecked 예외는 런타임에 발생 (선택적 처리)
  • ✅ Spring에서는 @ControllerAdvice로 전역 예외 처리
728x90
반응형