2011-05-16 167 views
242

嗯,我試圖理解和讀到的東西可能會導致它,但我只是無法得到它:什麼可能導致java.lang.reflect.InvocationTargetException?

我有我的代碼某處這樣的:

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

的事情是,當它試圖調用它拋出的某些方法 InvocationTargetException而不是某些其他預期的異常(具體爲ArrayIndexOutOfBoundsException)。 正如我真的知道調用什麼方法,我直接去了這個方法代碼,並添加了一個try-catch塊,假設這個代碼塊會拋出ArrayIndexOutOfBoundsException,並且它真的按照預期投擲了ArrayIndexOutOfBoundsException。然而,當它上漲時 以某種方式改變爲InvocationTargetException並且在上面的代碼中catch(Exception e) e是InvocationTargetException而不是ArrayIndexOutOfBoundsException 如預期的那樣。

什麼會導致這樣的行爲,或者我該如何檢查這樣的事情?

回答

263

您已通過調用具有反射的方法添加了一個額外的抽象級別。反射層包含InvocationTargetException中的任何異常,它允許您分辨異常實際上與反射調用中的失敗(例如,您的參數列表無效)導致的異常以及調用的方法中的失敗。

只需打開InvocationTargetException內的原因,就可以達到原來的原因。

+0

謝謝,但是我會怎樣區分(AssertionError e)和(Exception e)?如果我在展開原因之前總是首先得到InvocationTargetException,那麼每個異常之間的區別在哪裏? – user550413 2011-05-16 17:32:51

+3

@ user550413:當然,解開異常並檢查它。你可以隨時扔掉它,如果必須的話就可以用它來捕捉它。 – 2011-05-16 17:53:21

+119

對於任何人想知道「在InvocationTargetException中解開原因」是什麼意思,我只是發現如果你使用'exception.printStackTrace()'打印它,你只需看看「Caused By:」而不是上半部分/正常部分。 – Jan 2012-02-10 19:42:39

16

從Method.invoke的Javadoc中()

拋出:的InvocationTargetException - 如果底層方法拋出異常。

如果調用的方法拋出異常,則會引發此異常。

+0

所以想象一下,我有一個'java.lang.reflect.Proxy'實例級聯,用於擴充一個包裝對象。每個'Proxy'通過使用自己的'InvocationHandler'來優雅地處理特定的異常(可能由被包裝的對象拋出)。對於通過這個級聯直到到達正確的調用處理程序/代理的異常,在每個「InvocationHandler」中,我會捕獲「InvocationTargetException」,解開它,檢查包裝的異常是否是由此處理的異常「instanceof」 'InvocationHandler'。如果它不是'instanceof',我會拋出** unwrapped **異常......對吧? – Abdull 2013-02-25 15:07:30

+0

我總是會拋出未包裝的異常。 – 2013-03-05 23:02:59

39

的拋出異常如果

的InvocationTargetException - 如果底層方法拋出異常。

因此,如果該方法,已經被調用與反射API,將拋出異常(例如運行時異常),反射API將包裹該異常到InvocationTargetException

6

InvocationTargetException可能已經結束了你的ArrayIndexOutOfBoundsException。當使用反射方法可以拋出什麼時,沒有先知道 - 因此,而不是使用throws Exception方法,所有例外都被捕獲幷包裝在InvocationTargetException中。

+0

謝謝,但是我會如何區別(AssertionError e)和(Exception e)?如果我在展開原因之前總是首先得到InvocationTargetException,那麼每個異常之間的區別在哪裏? – user550413 2011-05-16 17:38:15

31

InvocationTargetException上使用getCause()方法檢索原始異常。

0
  1. 名單從Eclipse導航模式
  2. 所有jar文件確認所有jar文件在二進制模式
+2

如何通過在導航器中查看它們來驗證jar文件是否處於二進制模式? – William 2013-01-24 20:48:37

1

This描述類似,

的InvocationTargetException是經過檢查的異常該函數包裝由調用的方法或構造函數拋出的 異常。從版本 1.4開始,此異常已被改進以符合通用異常鏈接機制。在構建時提供並通過 getTargetException()方法訪問的「目標例外」 現在被稱爲原因,並且可能通過Throwable.getCause()方法以及 訪問前述方法。」

0

如果底層方法(使用Reflection調用的方法)拋出異常,則會引發此異常。

因此,如果反射API調用的方法引發異常(例如運行時異常),則反射API將將該異常包裝到InvocationTargetException中。

8

這將打印的準確代碼行的具體方法,它被調用時,引發的異常:我做 潔淨>運行xDoclet->運行xPackaging後

try { 

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

} catch (InvocationTargetException e) { 

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

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

謝謝;這幫助我意識到我的問題不在反思本身,而是在被調用的方法中。 – 2017-01-30 11:33:01

-6

錯誤消失了。

在我的工作區中,在ecllipse中。

1

您可以使用的getCause()方法原始異常類這樣的比較:

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

我面臨同樣的問題。我用e.getCause()。getCause()然後我發現它是因爲我傳遞的參數錯誤。在獲取其中一個參數的值時發生了nullPointerException。 希望這會幫助你。

0

我在外部classclass有來自呼叫記錄對象語句的java.lang.reflect.InvocationTargetException錯誤try/catch塊內。

通過Eclipse調試器&代碼步進將鼠標懸停我看到了記錄object記錄儀的聲明是null(需要在我class的最頂部被實例化一些外部常量)。

相關問題