[Java] InvocationTargetException 의 getCause 와 getTargetException
InvocationTargetException 에 대하여 아는대로 간략하게 적어본다.
틀린 점이나 보완할 점을 댓글로 적어주시기 바란다.
InvocationTargetException 은 자바에서 invoke 를 수행했을 때 오류가 발생하는 경우다.
invoke란 스트링 문자열을 통해 특정 클래스 내부의 메서드를 실행시키는 것으로, 이러한 기법을 리플렉션이라고 한다.
InvocationTargetException 은 스택 트레이스를 찍어봤자(ex.printStackTrace();) 의미있는 정보를 얻을 수 없다.
겉 껍데기에 불과한 InvocationTargetException 의 스택 트레이스만 찍히기 때문이다.
따라서 cause(ex.getCause())의 스택 트레이스를 찍어야 유의미한 정보를 얻을 수 있다.
ex.getCause().printStackTrace();
그런데 이 때 cause가 null인 경우가 있다. (ex.getCause() == null)
100% 그러한지는 모르겠는데, 경험적으로는 invoke한 메서드 내에서 Exception 이 발생한 경우가 아니라 Error 가 발생한 경우다.
이 경우 cause가 null 이다.
참고로 Exception 과 Error 는 똑같이 Throwable 객체를 상속받은 친구들이다.
invoke한 메서드 내에서 Error가 발생하는 사례를 들자면, 일부 클래스 파일 패치가 누락되어 특정 필드(특정 클래스의 멤버변수)를 찾을 수 없는 경우다. 이 때 Error의 getMessage()를 찍어보면 Unresolved compilation problem: [필드명] cannot be resolved or is not a field 이다.
정리하면 InvocationTargetException 의 cause 는 null 이 될 수 있으므로, getCause() 의 스택 트레이스를 찍으려면 반드시 null 체크를 해야 한다.
참고로 getTargetException() 메서드가 있는데 Exception에는 없고 InvocationTargetException 에만 존재하는 메서드다.
따라서 Throwable targetThrowable = ((InvocationTargetException) ex).getTargetException(); 이렇게 Exception 을 캐스팅(형 변환)해야 하여 getTargetException() 메서드를 사용할 수 있다. getTargetException() 은 내부적으로 멤버변수인 terget 을 리턴하는 메서드로, getCause() 와 동일하다고 생각하면 된다.
글로 쓴 내용을 소스코드로 정리하면 다음과 같다.
|
// InvocationTargetException 은 자바에서 invoke 를 수행했을 때 오류가 발생하는 경우 // invoke 대상에서 Exception 이 아닌 Error 가 발생한 경우 cause 가 null 인 InvocationTargetException 넘어옴 System.err.println(ex.getMessage()); } 또는 // InvocationTargetException 은 자바에서 invoke 를 수행했을 때 오류가 발생하는 경우 // invoke 대상에서 Exception 이 아닌 Error 가 발생한 경우 cause 가 null 인 InvocationTargetException 넘어옴 Throwable targetThrowable = ((InvocationTargetException) ex).getTargetException(); System.err.println(targetThrowable.getMessage()); } |