Menu
Coddy logo textTech

예외 클래스 계층 구조

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 59번째.

Java의 예외 처리 시스템은 Throwable 클래스에 뿌리를 둔 잘 조직된 클래스 계층 구조를 기반으로 구축되었습니다. 이 계층 구조를 이해하면 예외를 더 효과적으로 포착하고 처리하는 데 도움이 됩니다.

최상위에는 모든 예외와 오류의 부모인 Throwable이 위치합니다. 여기에는 두 개의 직접적인 하위 클래스가 있습니다:

Throwable
├── Error          // 심각한 문제 (이것들은 catch하지 마세요)
└── Exception      // 복구 가능한 문제
    └── RuntimeException  // 언체크 예외 (Unchecked exceptions)

ErrorOutOfMemoryError 또는 StackOverflowError와 같이 애플리케이션이 처리하려고 시도해서는 안 되는 심각한 문제를 나타냅니다. 이것들은 JVM 자체의 근본적인 문제를 나타냅니다.

Exception은 여러분이 가장 많이 다루게 될 브랜치입니다. 이는 두 가지 카테고리로 나뉩니다: 체크 예외(Exception의 직접적인 하위 클래스)와 언체크 예외(RuntimeException의 하위 클래스)입니다.

// 공통 예외 클래스
Exception
├── IOException           // 파일/네트워크 문제
├── SQLException          // 데이터베이스 문제
└── RuntimeException
    ├── NullPointerException
    ├── ArrayIndexOutOfBoundsException
    └── IllegalArgumentException

예외는 클래스이기 때문에 상속 규칙을 따릅니다. 부모 예외 타입을 catch하면 그 자식 예외들도 모두 catch하게 됩니다:

try {
    // 일부 코드
} catch (Exception e) {
    // 모든 예외를 포착합니다 (보통 너무 광범위함)
}
try {
    // 일부 코드
} catch (RuntimeException e) {
    // 런타임 예외 및 그 하위 클래스들만 캐치합니다
}

이 계층 구조를 통해 에러를 처리할 때 필요한 만큼 구체적이거나 일반적인 방식을 선택할 수 있으며, 이는 사용자 정의 예외를 만들기 위한 기초가 됩니다.

challenge icon

챌린지

쉬움

Java의 예외 계층 구조가 실제로 어떻게 작동하는지 보여주는 예외 분석기를 만들어 봅시다! 다양한 수준의 구체성에서 예외를 포착하고 어떤 유형이 포착되었는지 보고하는 시스템을 만들게 됩니다.

코드는 세 개의 파일로 구성됩니다:

  • ExceptionThrower.java: 입력에 따라 서로 다른 유형의 예외를 발생시킬 수 있는 클래스를 만듭니다. 클래스에는 세 개의 정적 메서드가 있어야 합니다:

    triggerRuntime(String type) - type 문자열에 따라 서로 다른 런타임 예외를 발생시킵니다:

    • type이 "null"이면, 메시지가 "Null value encountered"NullPointerException을 발생시킵니다.
    • type이 "index"이면, 메시지가 "Invalid index"ArrayIndexOutOfBoundsException을 발생시킵니다.
    • type이 "argument"이면, 메시지가 "Bad argument"IllegalArgumentException을 발생시킵니다.

    triggerArithmetic() - 메시지가 "Division error"ArithmeticException을 발생시킵니다.

    triggerGeneric() - 메시지가 "Generic runtime error"IllegalStateException을 발생시킵니다 (계층 구조는 Exception > RuntimeException > IllegalStateException입니다).

  • ExceptionAnalyzer.java: 서로 다른 계층 수준에서 예외를 포착하고 무엇이 포착되었는지 식별하는 클래스를 만듭니다. 다음 정적 메서드들을 포함하세요:

    analyzeSpecific(String type) - try 블록 내에서 ExceptionThrower.triggerRuntime(type)을 호출합니다. NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException에 대해 별도의 catch 블록을 사용하세요. 각 블록에서 Caught specific: [exception class simple name]를 출력하고 이어서 Message: [exception message]를 출력합니다.

    analyzeWithParent() - try 블록 내에서 ExceptionThrower.triggerArithmetic()을 호출합니다. 부모 유형인 RuntimeException을 사용하여 포착합니다. Caught via parent: RuntimeException를 출력하고 이어서 Actual type: [exception class simple name]를 출력합니다.

    analyzeWithGrandparent() - try 블록 내에서 ExceptionThrower.triggerGeneric()을 호출합니다. 계층 구조에서 더 높은 Exception을 사용하여 포착합니다. Caught via grandparent: Exception를 출력하고 이어서 Actual type: [exception class simple name]를 출력합니다.

  • Main.java: 예외 분석기를 하나로 합칩니다! 하나의 입력으로 예외 유형 문자열("null", "index", 또는 "argument" 중 하나)을 받게 됩니다.

    먼저, === Specific Catch ===를 출력하고 입력값과 함께 analyzeSpecific을 호출합니다.

    그 다음 빈 줄 하나와 === Parent Catch ===를 출력하고 analyzeWithParent를 호출합니다.

    마지막으로 빈 줄 하나와 === Grandparent Catch ===를 출력하고 analyzeWithGrandparent를 호출합니다.

하나의 입력을 받게 됩니다: 발생시킬 예외 유형("null", "index", 또는 "argument").

예외의 클래스 이름을 가져오려면 e.getClass().getSimpleName()을 사용하고, 메시지를 검색하려면 e.getMessage()를 사용하세요. 이 챌린지는 부모 예외 유형을 포착하면 모든 자식 예외도 포착된다는 것을 보여줍니다. 이는 예외 처리를 얼마나 구체적으로 할지 결정할 때 핵심적인 개념입니다!

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String type = scanner.nextLine();
        
        // TODO: "=== Specific Catch ==="을 출력하고 ExceptionAnalyzer.analyzeSpecific(type)을 호출하세요
        
        // TODO: 빈 줄을 출력한 다음 "=== Parent Catch ==="을 출력하고 ExceptionAnalyzer.analyzeWithParent()를 호출하세요
        
        // TODO: 빈 줄을 출력한 다음 "=== Grandparent Catch ==="을 출력하고 ExceptionAnalyzer.analyzeWithGrandparent()를 호출하세요
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨