2012-04-18 41 views
7

Làm cách nào để ném lại ngoại lệ đích của một InvocationTargetException. Tôi có một phương thức sử dụng sự phản chiếu để gọi phương thức invoke() trong một trong các lớp của tôi. Tuy nhiên, nếu có một ngoại lệ được ném trong mã của tôi, tôi không quan tâm đến InvocationTargetException và chỉ muốn ngoại lệ đích. Dưới đây là ví dụ:Tái ném một ngoại lệ đích InvocationTargetException

public static Object executeViewComponent(String name, Component c, 
     HttpServletRequest request) throws Exception { 

    try { 
     return c.getClass() 
       .getMethod(c.getMetaData().getMethod(), HttpServletRequest.class) 
       .invoke(c, request); 
    } catch (InvocationTargetException e) { 
     // throw the target exception here 
    } 
} 

Vấn đề chính mà tôi đang gặp phải là gọi ném e.getCause(); không ném một ngoại lệ mà là ném một Throwable. Có lẽ tôi đang tiếp cận điều này không chính xác?

Trả lời

12
catch (InvocationTargetException e) { 
    if (e.getCause() instanceof Exception) { 
     throw (Exception) e.getCause(); 
    } 
    else { 
     // decide what you want to do. The cause is probably an error, or it's null. 
    } 
} 
+0

+1 để thêm vào kiểm tra loại. –

+0

Làm thế nào bạn có thể có nguyên nhân 'null' cho một InvocationTargetException? –

+0

Tôi không nghĩ nó sẽ là nguyên nhân khi ngoại lệ này được Method.invoke(), nhưng InvocationTargetException có một hàm tạo cho phép một đích rỗng, vì vậy trong các tình huống khác, nó có thể là null. Tôi không biết chắc chắn, từ tài liệu API Method.invoke, nếu một lỗi được gói bên trong một InvocationTargetException của ném như là. –

0

Bạn có thể rethrow bất kỳ ngoại lệ bạn bắt trước bằng cách sử dụng các từ khóa ném và các đối tượng tương ứng bạn bắt:

catch (XXXException e) 
{ 
     throw e; 
} 
+0

OP muốn nguyên nhân của InvocationTargetException –

+0

Điều này chỉ ném cùng ngoại lệ. Tôi muốn "ăn" InvocationTargetException và chỉ ném ngoại lệ đích. –

+0

thì bạn phải làm: ném (Ngoại lệ) e.getCause(); (như Tim Bender đã nói) – Stephan

2

Exception#getCause trả về một Throwable. Nếu bạn muốn trình biên dịch nghĩ rằng bạn đang ném một số Exception thì có thể bạn cần truyền nó.

throw (Exception) e.getCause(); 
-1

Bạn có thể rethrow nguyên nhân mà không cần khai báo nó một cách rõ ràng.

public static Object executeViewComponent(String name, Component c, 
     HttpServletRequest request) throw /* known exceptions */ { 

    try { 
     return c.getClass() 
       .getMethod(c.getMetaData().getMethod(), HttpServletRequest.class) 
       .invoke(c, request); 
    } catch (InvocationTargetException e) { 
     // rethrow any exception. 
     Thread.currentThread().stop(e.getCause()); 
    } 
} 
+0

nó hoạt động, nhưng nó nguy hiểm. Phương thức stop() đã không được chấp nhận vì một lý do chính đáng. Đây là từ tài liệu API stop(): Không được chấp nhận Phương pháp này vốn đã không an toàn. Xem stop() để biết chi tiết. Một mối nguy hiểm bổ sung của phương thức này là nó có thể được sử dụng để tạo ra các ngoại lệ mà luồng đích không chuẩn bị để xử lý (bao gồm các ngoại lệ đã kiểm tra mà luồng không thể ném, không phải là phương thức này). Để biết thêm thông tin, hãy xem Tại sao Thread.stop, Thread.suspend và Thread.resume không được chấp nhận ?. – dgt

0

Dưới đây là tiết, nhưng tôi muốn tránh phản ánh và truyền. Tôi không nghĩ (nhưng không chắc chắn) rằng cú pháp đa cú pháp của Java 7 sẽ hữu ích.

public static Object executeViewComponent(String name, Component c, 
     HttpServletRequest request) throw KnownException_1 , KnownException_2 , ... , KnownException_n { 

    try { 
     return c.getClass() 
       .getMethod(c.getMetaData().getMethod(), HttpServletRequest.class) 
       .invoke(c, request); 
    } 
    catch (InvocationTargetException cause) 
    { 
      assert cause . getCause () != null : "Null Cause" ; 
      try 
      { 
       throw cause . getCause () ; 
      } 
      catch (KnownException_1 c) 
      { 
       throw c 
      } 
      catch (KnownException_2 c) 
      { 
       throw c 
      } 
      ... 
      catch (KnownException_n c) 
      { 
       throw c 
      } 
      catch (RuntimeException c) 
      { 
       throw c ; 
      } 
      catch (Error c) 
      { 
       throw c ; 
      } 
      catch (Throwable c) 
      { 
       assert false : "Unknown Cause" ; 
      } 
    } 
} 
Các vấn đề liên quan