자바에서 예외 처리를 하다 보면 발생한 예외 자체보다 그 근본 원인(root cause)을 알고 싶은 경우가 많습니다. 이때 유용하게 쓰이는 것이 Throwable 클래스에 정의된 getCause() 메소드입니다.
getCause() 메소드는 해당 예외의 원인(cause)을 반환하며, 원인이 설정되어 있지 않거나 알 수 없는 경우에는 null을 반환합니다. 이 메소드는 인자를 받지 않으며, 예외를 직접 던지지도 않습니다. 반환되는 원인은 생성자를 통해 전달되었거나 initCause() 메소드를 통해 설정된 값입니다.
예외 체이닝(exception chaining)은 하나의 예외가 다른 예외를 유발하는 상황에서 디버깅에 매우 중요합니다. getCause()를 활용하면 여러 겹으로 감싸진 예외 속에서 최초의 오류 지점까지 추적할 수 있습니다.
문법(Syntax)
public Throwable getCause()
예제 코드
아래 예제에서는 배열 범위를 초과하는 접근으로 ArrayIndexOutOfBoundsException이 발생하고, 이를 새로운 예외의 원인으로 설정한 뒤 다시 던지는 과정을 보여줍니다.
public class GetCauseMethodTest {
public static void main(String[] args) throws Exception {
try {
myException();
} catch(Exception e) {
System.out.println("Cause = " + e.getCause());
}
}
public static void myException() throws Exception {
int arr[] = {1, 3, 5};
try {
System.out.println(arr[8]); // 존재하지 않는 인덱스 접근
} catch(ArrayIndexOutOfBoundsException aiobe) {
Exception e = new Exception();
e.initCause(aiobe); // getCause()가 반환할 원인 설정
throw e; // main()의 catch 블록에서 잡히도록 예외 던지기
}
}
}실행 결과
Cause = java.lang.ArrayIndexOutOfBoundsException: 8
핵심 포인트 정리
- getCause()는 Throwable 객체의 원인 예외를 반환하며, 원인이 없으면 null을 반환합니다.
- initCause(Throwable cause) 메소드로 예외의 원인을 사후에 설정할 수 있으며, 반드시 throw 이전에 호출해야 합니다.
- 생성자
new Exception(String message, Throwable cause)형태로 객체를 생성하면 원인을 한 번에 지정할 수도 있습니다. - 예외 체이닝을 활용하면 로그 분석 시 근본 원인을 빠르게 파악할 수 있어 디버깅 효율이 크게 향상됩니다.
실무에서는 예외를 잡아서 다른 예외로 감쌀 때 반드시 원래 예외를 원인으로 포함하는 습관을 들이는 것이 좋습니다. 그렇지 않으면 최초의 오류 정보가 사라져 문제 해결이 어려워질 수 있습니다.