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

자바 메소드 오버라이딩 시 예외 처리 규칙 완벽 정리

메소드 재정의(오버라이딩)만으로 예외 처리를 변경할 수 있을까?

결론부터 말하면 가능합니다. 자바에서는 부모 클래스의 메소드를 재정의(오버라이드)할 때, 메소드 로직 전체를 바꾸지 않고도 예외 처리 방식만 변경하는 것이 허용됩니다. 다만, 이 경우 반드시 지켜야 할 세 가지 규칙이 있습니다.

규칙 1. 비검사 예외(Unchecked Exception)는 자유롭게 던질 수 있다

재정의하는 메소드는 부모 메소드가 예외를 던지는지 여부와 상관없이 비검사 예외(RuntimeException 및 그 하위 클래스)를 얼마든지 던질 수 있습니다. NullPointerException, ArithmeticException 등이 대표적인 예이며, 이러한 예외는 메소드 시그니처에 선언하지 않아도 되기 때문에 제약이 없습니다.

규칙 2. 새로운 검사 예외(Checked Exception)나 더 넓은 범위의 검사 예외는 던질 수 없다

재정의하는 메소드는 부모 메소드가 선언하지 않은 새로운 검사 예외를 던지거나, 부모 메소드가 선언한 예외보다 더 넓은(broader) 범위의 검사 예외를 던져서는 안 됩니다. 이를 위반하면 컴파일 오류가 발생합니다. 이는 다형성(polymorphism) 환경에서 호출자가 부모 타입 기준으로 예외를 처리하기 때문입니다.

규칙 3. 더 좁거나 더 적은 수의 예외는 던질 수 있다

반대로, 재정의하는 메소드는 부모 메소드가 선언한 예외보다 더 좁은(narrower) 범위의 하위 예외를 던지거나, 아예 예외를 던지지 않는 것도 허용됩니다. 즉, 예외 범위를 줄이는 방향은 항상 안전합니다.

예제 코드

import java.io.IOException;

class Parent {
    void display() throws Exception {
        System.out.println("부모 클래스 메소드");
    }
}

class Child extends Parent {
    // 부모(Exception)보다 좁은 IOException을 던지므로 유효함
    @Override
    void display() throws IOException {
        System.out.println("자식 클래스 메소드");
    }
}

위 예제에서 자식 클래스는 부모가 선언한 Exception보다 좁은 범위인 IOException을 던지므로 문제없이 컴파일됩니다. 그러나 자식이 SQLException처럼 상속 관계가 없는 새로운 검사 예외를 던지려 한다면 컴파일 오류가 발생합니다.

핵심 요약

  • 비검사 예외(RuntimeException 계열): 조건 없이 자유롭게 추가 가능
  • 검사 예외(Checked Exception): 새로 추가하거나 더 넓게 확장하는 것은 불가
  • 예외 범위 축소 또는 생략: 항상 허용됨

이 규칙들을 기억해 두면 오버라이딩 시 발생하는 컴파일 오류를 사전에 예방하고, 보다 안정적인 예외 처리 설계를 할 수 있습니다.