본문 바로가기
Language/Java

[JAVA] 다중 catch 블록 작성 시 주의점 : 예외 상속 계층의 이해

by Papa Martino V 2026. 1. 20.
728x90

다중 catch 블록
다중 catch 블록

 

자바 프로그래밍에서 예외 처리(Exception Handling)는 프로그램의 안정성을 결정짓는 핵심적인 요소입니다. 특히 하나의 try 블록에서 여러 개의 예외가 발생할 수 있을 때 사용하는 다중 catch 블록은 매우 유용하지만, 작성 시 반드시 지켜야 할 '상속 관계의 규칙'이 있습니다. 이 규칙을 어길 경우 컴파일 에러가 발생하여 코드 실행조차 불가능해집니다. 오늘 포스팅에서는 자바 개발자가 흔히 실수하기 쉬운 다중 catch 블록의 배치 순서와 상속 계층 구조가 미치는 영향에 대해 심도 있게 다뤄보겠습니다.

1. 다중 catch 블록의 기본 개념

다중 catch 블록은 하나의 예외 상황이 아닌, 발생 가능한 여러 시나리오를 각각 별도의 방식으로 처리하고자 할 때 사용합니다. 예를 들어, 파일을 읽는 과정에서 파일이 없을 때(FileNotFoundException)와 데이터를 읽는 도중 형식 오류가 발생할 때(IOException)를 나누어 처리하는 식입니다.

2. 핵심 주의점: 예외 클래스의 상속 관계

가장 중요한 원칙은 "하위 클래스 예외를 먼저 catch하고, 상위 클래스 예외를 나중에 catch해야 한다"는 것입니다. 자바의 예외 클래스들은 Throwable을 최상위로 하여 계층 구조를 형성하고 있습니다.

왜 순서가 중요한가?

자바 가상 머신(JVM)은 예외가 발생하면 위에서부터 순차적으로 catch 블록을 검사합니다. 만약 상위 클래스(부모)가 위에 있다면, 하위 클래스(자식) 예외는 부모 타입에도 해당하기 때문에 항상 부모 catch 블록에서 먼저 걸리게 됩니다. 이로 인해 아래쪽에 작성된 자식 catch 블록은 '도달할 수 없는 코드(Unreachable Code)'가 되어 컴파일러가 에러를 발생시킵니다.

3. 예외 상속 구조 비교 요약

다음은 주요 예외 클래스들의 상속 관계와 다중 catch 시 권장되는 배치 순서입니다.

구분 상위 클래스 (부모) 하위 클래스 (자식) 작성 권장 순서
입출력 관련 IOException FileNotFoundException FileNotFoundException → IOException
실행 시 예외 RuntimeException NullPointerException, ArithmeticException 등 세부 예외 → RuntimeException
범용 예외 Exception 모든 체크드/언체크드 예외 구체적 예외 → Exception (최하단)

4. Sample Example: 잘못된 예와 올바른 예

❌ 컴파일 에러가 발생하는 잘못된 코드

try {
    FileInputStream fis = new FileInputStream("test.txt");
    int data = fis.read();
} catch (IOException e) { 
    // IOException은 FileNotFoundException의 부모입니다.
    System.out.println("일반적인 입출력 오류 발생");
} catch (FileNotFoundException e) { 
    // 컴파일 에러: Unreachable catch block for FileNotFoundException.
    System.out.println("파일을 찾을 수 없습니다.");
}

✅ 정상적으로 동작하는 올바른 코드

try {
    FileInputStream fis = new FileInputStream("test.txt");
    int data = fis.read();
} catch (FileNotFoundException e) {
    // 가장 구체적인(하위) 예외를 먼저 배치
    System.out.println("특수 상황: 파일을 찾을 수 없습니다. 경로를 확인하세요.");
} catch (IOException e) {
    // 포괄적인(상위) 예외를 나중에 배치
    System.out.println("일반 상황: 파일 읽기 중 오류가 발생했습니다.");
} catch (Exception e) {
    // 예상치 못한 모든 최상위 예외 처리
    System.out.println("기타 알 수 없는 오류 발생");
}

5. 독창적인 팁: Multi-catch 블록의 활용

Java 7부터는 상속 관계가 없는 예외들을 한 줄로 처리할 수 있는 'Multi-catch' 기능이 도입되었습니다. 코드의 중복을 획기적으로 줄여줍니다. 단, 이때도 나열된 예외들 사이에 상속 관계가 있으면 안 됩니다.

// 상속 관계가 없는 경우 파이프(|) 기호로 병합 가능
try {
    // ... logic
} catch (NullPointerException | ArithmeticException e) {
    System.out.println("런타임 관련 데이터 오류 처리");
}

6. 결론 및 SEO 최적화 제언

다중 catch 블록을 작성할 때는 "작은 것에서 큰 것으로(Specific to General)" 흐름을 기억하십시오. 이는 코드의 가독성을 높일 뿐만 아니라, 예외 상황에 따른 정밀한 대응을 가능하게 합니다. 전문적인 자바 개발자라면 단순히 에러를 막는 것을 넘어, 예외 계층 구조를 이용해 사용자에게 더 정확한 피드백을 제공해야 합니다.


내용 출처:
- Oracle Java Documentation: Catching Multiple Exception Types
- Effective Java 3rd Edition (Joshua Bloch)
- Java Language Specification (JLS) Chapter 11. Exceptions

728x90