Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java의 도달 불가능한(Unreachable) catch 블록이란? 개념과 발생 원인 완벽 정리

어떠한 경우에도 프로그램의 제어 흐름이 도달할 수 없는 문장 블록을 도달 불가능한(unreachable) 블록이라고 합니다. Java는 이러한 도달 불가능한 블록을 지원하지 않으며, 컴파일 시점에 오류로 판단합니다.

Exception 클래스를 매개변수로 사용하는 catch 블록은 반드시 마지막에 위치해야 합니다. Exception은 모든 예외 클래스의 슈퍼클래스(상위 클래스)이기 때문입니다. 따라서 여러 개의 catch 블록을 작성할 때는 가장 구체적인(specific) 예외부터 가장 일반적인(general) 예외 순으로 배치해야 합니다. 즉, Exception의 하위 클래스들이 먼저 오고 상위 클래스들이 나중에 와야 합니다. 만약 상위 클래스를 먼저 배치하고 하위 클래스를 나중에 배치하면, 컴파일러는 도달 불가능한 catch 블록(unreachable catch block) 오류를 발생시킵니다.

문법(Syntax)

try {
    // 실행 문장
} catch(Exception e) {
    System.out.println(e);
} catch(NumberFormatException nfe) { // 도달 불가능한 블록. Java가 지원하지 않으므로 컴파일 오류 발생
    System.out.println(nfe);
}

위 코드처럼 가장 일반적인 Exception을 먼저 잡으면, 그 뒤에 오는 NumberFormatException 블록에는 어떤 경우에도 제어가 도달할 수 없습니다.

catch 절이 '도달 가능'하다고 판단되는 조건

컴파일러는 다음 두 조건이 모두 참일 때 catch 절 C가 도달 가능하다고 판단합니다.

  • try 블록에서 던져진 체크드 예외(checked exception)가 C의 매개변수 타입에 할당(assignable) 가능한 경우
  • C의 매개변수 타입과 동일하거나 그 상위 타입(supertype)인 매개변수를 가진 이전 catch 절이 존재하지 않는 경우

catch 절이 '도달 불가능'하다고 판단되는 조건

반대로 다음 두 조건이 모두 참이면 해당 catch 절은 도달 불가능한 것으로 간주됩니다.

  • catch 절의 매개변수 타입 E가 어떠한 언체크드 예외(unchecked exception)도 포함하지 않는 경우
  • try 블록에서 던져지는 예외 중 타입이 E의 (엄격한) 하위 타입(subtype)인 모든 예외가 이미 앞선 catch 절들에 의해 처리되고 있는 경우

예제 코드

public class UnreachableBlock{
    public static void main(String[] args) {
        try {
            int i = Integer.parseInt("abc"); // 이 문장은 NumberFormatException을 던짐
        } catch(NumberFormatException nfe) {
            System.out.println("This block handles NumberFormatException");
        } catch(Exception e) {
            System.out.println("This block handles all exception types");
        } catch (Throwable t) {
            System.out.println("Throwable is super class of Exception");
        }
    }
}

위 예제는 올바른 순서로 catch 블록을 배치한 사례입니다. Integer.parseInt("abc")는 숫자가 아닌 문자열을 정수로 변환하려다 NumberFormatException을 발생시키며, 이 예외는 가장 구체적인 첫 번째 catch 블록이 처리합니다. 그다음으로 더 일반적인 Exception, 최상위 타입인 Throwable 순으로 배치했기 때문에 컴파일 오류 없이 정상적으로 동작합니다.

실행 결과(Output)

This block handles NumberFormatException