코드 저장소.

Exception 처리 (Checked vs Unchecked) 본문

Java

Exception 처리 (Checked vs Unchecked)

slown 2025. 9. 6. 00:17

목차

1.작성하게 된 계기

2.예외(Exception)란?

3. Checked Exception

4. Unchecked Exception

5. Checked vs Unchecked 비교

6. 실무 적용 관점

7. 결론

 

1.작성하게 된 계기

일전에 일정관리 프로젝트를 하면서 OpenAI API 응답(JSON 파싱)과 DB 조회를 묶어서 처리하는 코드를 작성했다.

@CircuitBreaker(name = "openAiClient", fallbackMethod = "fallbackRecommendSchedules")
public List<Schedules> recommendSchedules(String userId, Pageable pageable) throws Exception {
    Long memberId = memberRepository.findByUserId(userId)
            .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."))
            .getId();

    String extractedJson = ... // OpenAI 응답 JSON
    List<ScheduleRecommendationDto> recommendedList =
            objectMapper.readValue(extractedJson, new TypeReference<>() {}); // IOException 발생 가능

    return mapToRecommendedSchedules(recommendedList, memberId);
}

 

처음에는 단순히 throws Exception을 붙여 해결했는데, 멘토에게서 이런 피드백을 받았다.

 

이 피드백을 계기로 Checked Exception과 Unchecked Exception의 차이, 그리고 실무에서의 적용 방법을 정리해보았다.

2.예외(Exception)란?

Java에서 예외(Exception)는 프로그램 실행 중 발생하는 오류 상황을 의미합니다. 

 

크게 두 가지로 나뉜다

  • Error: 시스템 레벨에서 복구 불가능 (예: OutOfMemoryError, StackOverflowError)
  • Exception: 애플리케이션 레벨에서 발생, 복구 가능성 있음

Exception은 다시 Checked ExceptionUnchecked Exception으로 나뉜다.

3. Checked Exception

Checked Exception은 컴파일 시점에 반드시 처리를 강제하는 예외를 말합니다. 

 

  • 대표 예시: IOException, SQLException
  • 특징:
    • 호출한 쪽이 예외 처리 책임을 져야 함
    • 주로 외부 자원 접근(I/O, 네트워크, DB) 같은 복구 가능한 상황에서 발생
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    ...
} catch (IOException e) {
    // 파일 경로 잘못된 경우 복구 가능
}

 

4. Unchecked Exception

Unchecked Exception은 컴파일러가 체크하지 않는 예외. RuntimeException을 상속

 

  • 대표 예시: NullPointerException, IllegalArgumentException
  • 특징:
    • throws 선언 불필요
    • 보통 프로그래밍 오류나 복구 불가능한 상황에서 발생
public int divide(int a, int b) {
    return a / b; // b=0 → ArithmeticException 발생
}

 

5. Checked vs Unchecked 비교

구분 Checked Exception Unchecked Exception
상속 Exception RuntimeException
컴파일 타임 체크 O X
선언 강제 throws 필요 선언 불필요
대표 예시 IOException, SQLException NullPointerException, IllegalArgumentException
사용처 복구 가능한 외부 자원 문제 프로그래밍 오류, 복구 불가능 상황

 

6. 실무 적용 관점

실무에서는 Checked Exception을 그대로 쓰기보다, 대부분 Unchecked Exception으로 wrapping해서 던진다.

이유는 다음과 같다:

  1. 서비스/DAO 메서드마다 throws IOException 등을 선언하면 코드가 지저분해짐
  2. JSON 파싱 실패, DB 커넥션 끊김 등은 호출자가 복구할 수 없으므로 Checked로 던져봤자 의미가 없음
  3. Spring Framework도 DataAccessException처럼 Unchecked 기반 예외로 통일
try {
    List<ScheduleRecommendationDto> recommendedList =
        objectMapper.readValue(extractedJson, new TypeReference<>() {});
    return mapToRecommendedSchedules(recommendedList, memberId);
} catch (IOException e) {
    throw new IllegalStateException("추천 일정 JSON 파싱 실패", e); // Wrapping
}

7. 결론

  • Checked Exception은 복구 가능한 상황에서 의미가 있다.
  • Unchecked Exception은 대부분의 실무에서 선호되며, Checked를 그대로 던지지 않고 wrapping하는 게 바람직하다.
  • 나 역시 이번 경험을 통해 throws Exception을 남발하지 않고, 상황에 맞는 예외 설계를 고민하게 되었다.

예외를 단순히 “던지는 것”에서 끝내지 말고, “이 예외가 호출자에게 어떤 의미를 줄지”를 고려하는 게 중요하다.

 

 

 

'Java' 카테고리의 다른 글

GC(Garbage Collector)  (0) 2025.09.06
== vs equals(), hashCode()  (0) 2025.09.06
String vs StringBuilder vs StringBuffer  (0) 2025.09.05
GraalVM?  (0) 2025.08.05
객체 비교를 위한 Comparator , Comparable  (0) 2025.02.06