Java.lang.reflect.InvocationTargetException'a ne sebep olabilir?


313

Neyin sebep olabileceğini anlamaya ve okumaya çalıştım ama anlayamıyorum:

Benim kodda bir yerde var:

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

Bir şey, bir yöntemi çağırmaya çalıştığında, InvocationTargetExceptionbeklenen diğer bir istisna yerine (özellikle ArrayIndexOutOfBoundsException) atar . Aslında hangi yöntemin çağrıldığını bildiğim için doğrudan bu yöntem koduna gittim ve atması gereken hat için bir try-catch bloğu ekledim ArrayIndexOutOfBoundsExceptionve gerçekten ArrayIndexOutOfBoundsExceptionbeklendiği gibi fırladı . Yine de yukarı çıkarken InvocationTargetException, catch(Exception e) e'nin üstündeki kodda ve kodda bir şekilde değişiklikler beklendiği gibi InvocationTargetExceptiondeğil ArrayIndexOutOfBoundsException.

Böyle bir davranışa ne sebep olabilir veya böyle bir şeyi nasıl kontrol edebilirim?

Yanıtlar:


333

Yöntemi yansıma ile çağırarak fazladan bir soyutlama düzeyi eklediniz. Yansıtma tabakasının bir herhangi istisna sarar InvocationTargetExceptionbir istisna arasındaki farkı anlatmak sağlar, aslında yansıma çağrısında bir arıza nedeniyle (belki argüman listesi, örneğin geçerli değildi) ve denilen yöntemle içindeki bir başarısızlık.

Sadece içindeki nedeni açın InvocationTargetExceptionve orijinal olana ulaşacaksınız .


4
@ user550413: İstisnayı çözerek ve bunu inceleyerek elbette. Her zaman kendiniz fırlatabilir ve gerekirse yakalayabilirsiniz.
Jon Skeet

157
Herkes "içinde nedenini açmak" için ne anlama geldiğini merak için InvocationTargetException, sadece kullanarak yazdırdıysanız exception.printStackTrace(), sadece üst yarısı / normal bölüm yerine "Neden:" bölümüne baktığını keşfettim .
Ocak

31
"Paketin açılması" ile ilgili açıklamayı eklemek için, istisnayı da yakalayabilir ve istenirse yeniden yazılabilen getCause () yöntemini kullanabilirsiniz. Gibi bir şey try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) }veya...catch... { throw ex.getCause() }
jcadcell

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

1
@DheraajBhaskar Başkalarının yanıtlarını kendinizinmiş gibi düzenlemeyin ve alıntı yapılmamış metinler için alıntı biçimlendirmesi kullanmayın. Bu düzenleme yorum olarak yayınlanmış olmalıdır.
Lorne Marquis

51

İstisna atılırsa

InvocationTargetException - temel alınan yöntem bir istisna atarsa.

Dolayısıyla, yansıma API'siyle çağrılan yöntem bir istisna atarsa ​​(örneğin çalışma zamanı istisnası), yansıma API'sı istisnayı bir InvocationTargetException.


harika bir açıklama!
gaurav

Altta yatan yöntemin bir istisna atmasını beklersem ne olur? Bu istisnayı yakalamalı ve sadece tekrar mı söylemeliyim?
jDub9

46

Orijinal özel durumu almak için getCause()üzerindeki yöntemi kullanın InvocationTargetException.


21

Method.invoke () Javadoc sitesinden

Atar: InvocationTargetException - temel yöntem bir istisna atarsa.

Bu istisna, çağrılan yöntem bir istisna atarsa ​​atılır.


Öyleyse java.lang.reflect.Proxy, sarılmış bir nesneyi arttıran bir dizi çağrım olduğunu hayal edin . Her biri Proxy, kendi nesnesini kullanarak belirli bir istisnayı (muhtemelen sarılmış nesne tarafından atılan) incelikle işler InvocationHandler. Her doğru çağırma işleyici / vekil ulaşana kadar bu çağlayanı içinden dalgalanma ilişkin bir istisna için InvocationHandler, ben yakalamak istiyorum InvocationTargetExceptionsarılmış istisna bir ise bunun unwrap, çek, instanceofbu tarafından ele alınması için istisna InvocationHandler. Değilse instanceof, açılmamış istisnayı atacağım ... değil mi?
Abdull

Her zaman açılmamış istisnayı atarım.
Peter Lawrey

9

Yani InvocationTargetExceptionmuhtemelen yukarı senin tamamlıyor ArrayIndexOutOfBoundsException. Yansıtma kullanıldığında, bu yöntemin neler atabileceğini söylemek mümkün değildir - bu yüzden bir throws Exceptionyaklaşım kullanmak yerine , tüm istisnalar yakalanır ve içine sarılır InvocationTargetException.


Teşekkürler, ancak örneğin (AssertionError e) ve (Exception e) arasında nasıl farklılık göstereceğim? Sebebi açmadan önce her zaman InvocationTargetException'ı alırsam, her bir istisna arasında nerede farklılık göstereceğim?
user550413

9

Bu, çağrıldığında istisna oluşturan belirli yöntemdeki kod satırını yazdırır:

try {

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

} catch (InvocationTargetException e) {

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

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

1
Teşekkürler; bu, sorunumun yansımanın kendisinde değil, çağrılan yöntemde olduğunu anlamama yardımcı oldu.
Jose Gómez

3

Bu ,

InvocationTargetException, çağrılan bir yöntem veya yapıcı tarafından atılan bir özel durumu saran işaretli bir istisnadır. 1.4 sürümünden itibaren, bu istisna genel amaçlı istisna zincirleme mekanizmasına uyacak şekilde uyarlanmıştır. İnşaat zamanında sağlanan ve getTargetException () yöntemi ile erişilen "hedef özel durumu" artık neden olarak bilinir ve Throwable.getCause () yönteminin yanı sıra yukarıda belirtilen "eski yöntem" ile erişilebilir.


2

Aşağıdaki gibi getCause () yöntemini kullanarak orijinal istisna Sınıfı ile karşılaştırabilirsiniz:

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

1

Benim içinde bir / bloğu içinde java.lang.reflect.InvocationTargetExceptionharici bir logger nesnesi çağıran bir deyimden bir hata vardı .classtrycatchclass

Eclipse ayıklayıcısında kodu atlama & I logger gördüm logger deyimi üzerinden fare havada asılı objectidi null(gerekli bazı dışsal sabitleri Sesimin en üst kısmında örneği oluşturulacak class).


0

Altta yatan yöntem (Yansıma kullanılarak adlandırılan yöntem) bir istisna atarsa ​​bu istisna atılır.

Dolayısıyla, yansıma API'sı tarafından çağrılan yöntem bir istisna atarsa ​​(örneğin, çalışma zamanı istisnası gibi), yansıma API'sı istisnayı bir InvocationTargetException içine sarar.


0

Aynı sorunla karşı karşıyaydım. Ben e.getCause () kullandım. GetCause () sonra ben geçiyordu yanlış parametreleri nedeniyle bulundu. Parametrelerden birinin değerini getirirken nullPointerException vardı. Umarım bu sana yardımcı olur.


-2
  1. Eclipse Navigator modundaki tüm jar dosyalarını listele
  2. Tüm jar dosyalarının ikili modda olduğunu doğrulayın

4
Jar dosyalarının Navigator'da görüntüleyerek ikili modda olduğunu tam olarak nasıl doğrularsınız?
William

@William beni güldürdün hahaha. Bu adamın cevabı düşürülmeli.
Karim Manaouil

-7

Clean-> Run xDoclet-> Run xPackaging komutunu yaptıktan sonra hata kayboldu.

Çalışma alanımda, tutulmada.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.