minOS

자바의 정석 ch8-7~8 printStackTrace(),멀티 catch블럭 본문

TIL/남궁성의 자바의 정석

자바의 정석 ch8-7~8 printStackTrace(),멀티 catch블럭

minOE 2024. 9. 5. 19:05
728x90

ch8-7 printStackTrace() 와 getMessage()

- printStackTrace() : 예외 발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
- getMessage() : 발생한 예외 클래스의 인스턴스에 저장된 메세지를 얻을 수 있다.
public class Ex8_5 {
    public static void main(String[] args) {
        System.out.println(1);
        System.out.println(2);
        try {
            System.out.println(3);
            System.out.println(0 / 0);  // 예외 발생
            System.out.println(4);      // 실행되지 않는다.
        } catch (ArithmeticException ae) {
            // 예외가 ArithmeticException인 경우
            ae.printStackTrace();
            System.out.println("예외메세지 : " + ae.getMessage());
        }  // try-catch 끝
        System.out.println(6);  // 예외 처리 후 계속 실행
    }
}​

실행 결과

 

 

ch8-8 멀티 catch블럭

내용이 같은 catch블럭을 하나로 합친것(JDK1.7부터)

구조
try {
    // 예외가 발생할 수 있는 코드
} catch (ExceptionType1 | ExceptionType2 | ExceptionType3 e) {
    // ExceptionType1, ExceptionType2, ExceptionType3에 대한 공통 예외 처리
}


예외가 부모 - 자식 관계면 에러 발생 

public class Ex8_6 {
    public static void main(String[] args) {
        try {
            // 예외가 발생할 수 있는 코드
            riskyOperation();
        } catch (Exception | RuntimeException e) {  // 컴파일 에러 발생
            // Exception은 RuntimeException의 부모 클래스이므로 이 구문은 유효하지 않습니다.
            System.out.println("An error occurred: " + e.getMessage());
        }
    }

    public static void riskyOperation() throws RuntimeException {
        // 이 메서드는 RuntimeException을 발생시킬 수 있음
        throw new RuntimeException("Something went wrong");
    }
}



멀티 catch 블럭은 예외의 공통멤버만 사용 가능

class FirstException extends Exception {
    public void methodForFirst() {
        System.out.println("FirstException의 특별한 메서드");
    }
}

class SecondException extends Exception {
    public void methodForSecond() {
        System.out.println("SecondException의 특별한 메서드");
    }
}

public class MultiCatchCommonMemberExample {
    public static void main(String[] args) {
        try {
            if (Math.random() < 0.5) {
                throw new FirstException();
            } else {
                throw new SecondException();
            }
        } catch (FirstException | SecondException e) {
            // 공통 멤버만 사용 가능
            System.out.println("예외 메시지: " + e.getMessage());
            e.printStackTrace();

            // 다음 라인들은 컴파일 에러를 발생시킵니다:
            // e.methodForFirst();  // 컴파일 에러
            // e.methodForSecond(); // 컴파일 에러

            // 개별 예외의 특정 메서드를 사용하려면 타입 체크와 캐스팅이 필요합니다
            if (e instanceof FirstException) {
                ((FirstException) e).methodForFirst();
            } else if (e instanceof SecondException) {
                ((SecondException) e).methodForSecond();
            }
        }
    }
}

 

  1. FirstException과 SecondException은 각각 고유한 메서드를 가지고 있다.
  2. 멀티 catch 블록에서는 Exception 클래스의 공통 메서드만 직접 사용할 수 있다:
    • e.getMessage()
    • e.printStackTrace()
  3. 개별 예외의 특정 메서드(methodForFirst(), methodForSecond())를 직접 호출하려고 하면 컴파일 에러가 발생한다.
  4. 개별 예외의 특정 메서드를 사용하려면 instanceof 연산자로 타입을 확인하고 적절한 타입으로 캐스팅해야 한다.

이러한 제한이 있는 이유:

  • 멀티 catch 블록에서 잡히는 예외의 정확한 타입을 컴파일 시점에 알 수 없다.
  • 따라서 컴파일러는 안전하게 모든 잡히는 예외의 공통 상위 클래스(이 경우 Exception)의 멤버만 허용한다.

이 특성은 멀티 catch 블록을 사용할 때 주의해야 할 중요한 점이다. 개별 예외에 특화된 처리가 필요한 경우, 위 예제처럼 instanceof를 사용하여 타입을 확인하고 적절히 캐스팅하거나, 별도의 catch 블록을 사용하는 것이 좋다.

728x90