자바는 모든 것이 객체다. 

예외도 객체고 스레드도 객체고 너도 객체고 나도 객체다.

오늘은 간단히 예외처리의 부모자식 관계에 대해 포스팅하겠다!

 


예외도 위 아래가 있어요

예외도 상위 타입의 예외가 있고, 그것을 상속받는 하위 타입의 예외가 있다.

본 포스팅에서는 뭐가 상위 타입 예외이고 뭐가 하위 타입 예외인지에 대한 것이 중요한게 아니기 때문에, 설명은 패스한다.

 

이번 주제에 대한 쉬운 이해를 위해 아래와 같은 코드가 있다고 가정하자(실제 동작하는 코드는 아님)

//부모 클래스
class Parent {
   void method() throws InterruptedException {
   // ...
        }
    }
    
//자식 클래스
class Child extends Parent {
   @Override
   void method() throws Exception {
   // ...
        }
    }
    
public class Test {
	public static void main(String[] args) {
		Parent p = new Child();
			try {
				p.method();
			} catch (InterruptedException e) {
				// InterruptedException 처리
		}
	}
}

위 코드의 예시로, 실제 인스턴스의 타입은 Child이지만, Parent 타입으로 선언 했다고 가정하자.

컴파일 시점에 , p.method 라는 코드를 컴파일러 입장에서 Parent 타입의 메서드가 실행될 것으로 예측하고 Parent 타입의 메서드를 실행한다.

-> 즉 컴파일 시점에 Parent 메서드의 InterruptedException 예외가 터질것으로 예상하여 최종적으로 main 메서드에서도 InterruptedException 를 처리해야겠다고 예측하고 처리한다.

하지만 실제 런타임에서는 자식 인스턴스의 메서드(Child)의 메서드가 실행되고, 최상위 예외 타입인 Exception 예외가 터져버린다.

최종 main() 메서드에서는 이미 try/catch문으로 InterruptedException를 잡아 버렸는데, 이보다 상위 타입인 Exception 예외를 런타임에 잡아버리려고 하니 예외 처리가 불가해져 버렸다.


Java : 하지 말라는건 하지 마세요

Java에서는 이를 방지하기 위해 아래와 같은 제약들을 설정해두었다.

1. 자식 클래스에 재정의 된 메서드는 부모 메서드가 던질 수 있는 체크 예외의 하위 타입만 던질 수 있다. -> 즉 위 예제와 반대로 부모가 Exception 예외를 던지고 있다면 자식은 InterruptedException 예외 던지기 가능.

2. 원래 메서드가 체크 예외를 던지지 않는 경우, 재정의 된 메서드도 체크 예외를 던질 수 없다.

 

오늘의 결론 : 컴파일 안되는데는 이유가 있다.. 하지 말라는건 하지 말자!