java.lang.reflect.InvocationTargetException의 원인은 무엇입니까?


313

글쎄, 나는 그것을 일으킬 수있는 것을 이해하고 읽으려고 노력했지만 그것을 얻을 수는 없다.

내 코드 어딘가에 있습니다.

 try{
 ..
 m.invoke(testObject);
 ..
 } catch(AssertionError e){
 ...
 } catch(Exception e){
 ..
 }

그것은 어떤 메소드를 호출하려고 할 때 InvocationTargetException예상되는 다른 예외 (특히 ArrayIndexOutOfBoundsException) 대신 던집니다 . 실제로 메소드가 호출되는 것을 알다시피 나는이 방법을 코드로 바로 가서 던져 가정 선의 시도-catch 블록에 추가 ArrayIndexOutOfBoundsException하고이 정말 던졌다 ArrayIndexOutOfBoundsException예상대로입니다. 까지 갈 때 그러나 어떻게 든로 변경 InvocationTargetException하고 위의 코드 catch(Exception e) 입니다 전자 InvocationTargetException하지 ArrayIndexOutOfBoundsException 예상대로.

그러한 행동을 유발할 수있는 원인은 무엇입니까?

답변:


333

리플렉션을 사용하여 메소드를 호출하여 추가 추상화 레벨을 추가했습니다. 반사 층은 어떤 예외 랩 InvocationTargetException은 예외 사이의 차이를 알려주는 기능, 실제로 반사 호출 실패로 인한를 (어쩌면 당신의 인수 목록은 예를 들어, 유효하지 않습니다) 및 호출 된 메소드 내에서 오류가 발생했습니다.

내부에서 원인을 풀면 InvocationTargetException원래 원인으로 이동합니다.


4
@ user550413 : 물론 예외를 풀고 검사하여. 당신은 항상 그것을 스스로 던질 수 있고, 필요할 경우 그렇게 잡을 수 있습니다.
Jon Skeet

157
"내에서 원인을 풀다"는 것이 무엇을 의미하는지 궁금한 사람은 InvocationTargetException방금을 사용하여 인쇄 한 경우 exception.printStackTrace()상반기 / 일반 섹션 대신 "Caused By :"섹션을 보면 된다는 것을 알게되었습니다 .
Jan

31
"unwrapping"에 대한 설명을 추가하기 위해 예외를 잡아서 getCause () 메소드를 사용할 수도 있습니다. 원하는 경우 다시 던질 수도 있습니다. 뭔가 같은 try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) }...catch... { throw ex.getCause() }
jcadcell

4
+1 @HJanrs you just look at the "Caused By:" section instead of the top half/normal section
GingerHead

1
@DheraajBhaskar 다른 사람의 답변을 자신의 답변처럼 편집하지 말고 인용되지 않은 텍스트에는 인용 형식을 사용하지 마십시오. 해당 수정 사항은 의견으로 게시되어야합니다.
Lorne의 후작

51

다음과 같은 경우 예외가 발생합니다.

InvocationTargetException-기본이되는 메소드가 예외를 throw하는 경우

리플렉션 API로 호출 된 메소드가 예외 (예 : 런타임 예외)를 발생시키는 경우 리플렉션 API는 예외를로 묶습니다 InvocationTargetException.


좋은 설명!
gaurav

기본 메소드가 예외를 발생시킬 것으로 예상되면 어떻게합니까? 이 예외를 잡아서 다시 던져야합니까?
jDub9

46

getCause()메소드를 사용하여 InvocationTargetException원래 예외를 검색하십시오.


21

Method.invoke ()의 Javadoc에서

InvocationTargetException-기본이되는 메소드가 예외를 throw하는 경우

이 메소드는 호출 된 메소드가 예외를 발생시킨 경우 발생합니다.


java.lang.reflect.Proxy래핑 된 객체를 보강하는 일련의 인스턴스 가 있다고 상상해보십시오 . 각각 Proxy은 고유 한을 사용하여 특정 예외 (랩 된 객체에 의해 throw 될 수 있음)를 정상적으로 처리합니다 InvocationHandler. 각각 올바른 호출 핸들러 / 프록시에 도달 할 때까지이 캐스케이드를 통해 리플 예외를 들어 InvocationHandler, I 잡을 것이다 InvocationTargetException랩 예외가되어 있으면 풀다 확인 instanceof이 처리 할 수있는 예외 InvocationHandler. 그것이이 아니라면 instanceof, 나는 던질 것 미개봉 예외 ... 괜찮아?
Abdull

나는 항상 래핑되지 않은 예외를 던질 것입니다.
Peter Lawrey

9

그건 InvocationTargetException아마 최대 당신의 포장됩니다 ArrayIndexOutOfBoundsException. 리플렉션을 사용할 때 해당 메소드가 던질 수있는 것을 미리 알 수는 없습니다. 따라서 throws Exception접근 방식을 사용하는 대신 모든 예외가 포착되고 마무리됩니다 InvocationTargetException.


고맙지 만 예를 들어 (AssertionError e)와 (Exception e)의 차이점은 무엇입니까? 원인을 풀기 전에 항상 InvocationTargetException을 먼저 얻는 경우 각 예외 사이의 차이점은 무엇입니까?
user550413

9

이렇게하면 특정 메소드에 정확한 코드 줄이 인쇄되어 호출되면 예외가 발생합니다.

try {

    // try code
    ..
    m.invoke(testObject);
    ..

} catch (InvocationTargetException e) {

    // Answer:
    e.getCause().printStackTrace();
} catch (Exception e) {

    // generic exception handling
    e.printStackTrace();
}

1
감사; 이것은 내 문제가 반영 자체가 아니라 호출 된 메소드 내에 있음을 깨닫는 데 도움이되었습니다.
Jose Gómez

3

이것은 다음과 같은 것을 설명합니다.

InvocationTargetException은 호출 된 메소드 또는 생성자에 의해 발생 된 예외를 랩핑하는 점검 된 예외입니다. 릴리스 1.4부터이 예외는 범용 예외 체인 메커니즘을 준수하도록 개선되었습니다. 구성시 제공되고 getTargetException () 메소드를 통해 액세스되는 "대상 예외"는 이제 원인으로 알려져 있으며 Throwable.getCause () 메소드 및 위에서 언급 한 "레거시 메소드"를 통해 액세스 할 수 있습니다.


2

다음과 같이 getCause () 메소드를 사용하여 원래 예외 클래스와 비교할 수 있습니다.

try{
  ...
} catch(Exception e){
   if(e.getCause().getClass().equals(AssertionError.class)){
      // handle your exception  1
   } else {
      // handle the rest of the world exception 
   }
} 

1

java.lang.reflect.InvocationTargetException외부 classtry/ catch블록 내부 에서 로거 객체를 호출하는 문에서 오류가 발생했습니다 class.

Eclipse 디버거에서 코드를 단계별로 실행하고 로거 문 위로 마우스를 가져 가면 로거 object가 보였습니다 null(일부 외부 상수는 내 맨 위에 인스턴스화해야했습니다 class).


0

기본이되는 메소드 (Reflection을 사용하여 호출 된 메소드)가 예외를 throw하면이 예외가 발생합니다.

리플렉션 API에 의해 호출 된 메소드가 예외 (예 : 런타임 예외)를 발생 시키면 리플렉션 API는 예외를 InvocationTargetException으로 랩핑합니다.


0

나는 같은 문제에 직면했다. 나는 e.getCause (). getCause ()를 사용했다. 그러면 매개 변수가 잘못되었다는 것을 알았다. 매개 변수 중 하나의 값을 가져 오는 중에 nullPointerException이 발생했습니다. 이것이 도움이되기를 바랍니다.


-2
  1. Eclipse Navigator 모드에서 모든 jar 파일을 나열하십시오.
  2. 모든 jar 파일이 2 진 모드인지 확인하십시오.

4
네비게이터에서 jar 파일을보고 바이너리 파일인지 정확히 어떻게 확인합니까?
William

@ William 당신은 나를 하하하 웃게 만들었습니다. 이 사람의 대답은 하향 조정되어야합니다.
Karim Manaouil

-7

Clean-> Run xDoclet-> Run xPackaging을 수행 한 후 오류가 사라졌습니다.

내 작업 공간에서 ecllipse로.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.