Java:如何捕获 Method.invoke 内创建的异常?

问题描述 投票:0回答:5

当从 Method.invoke 方法调用该方法时,我似乎无法捕获代码中的异常。如何从方法本身内部捕获它?

void function() {
  try {
    // code that throws exception
  }
  catch( Exception e ) {
    // it never gets here!! It goes straight to the try catch near the invoke
  }
}

try {
  return method.invoke(callTarget, args);
}
catch( InvocationTargetException e ) {
  // exception thrown in code that throws exception get here!
}

谢谢!

java exception invoke
5个回答
5
投票

您可以通过检查其

MethodInvocationException
方法来获取
getCause()
的真正原因,该方法将返回从
function()

抛出的异常

注意:您可能需要在返回的异常上递归调用

getCause()
才能到达您的异常。

注意

getCause()
返回一个
Throwable
,您必须检查其实际类型(例如
instanceof
getClass()

注意:如果没有更多“原因”可用,

getCause()
返回
null
——您已经找到了抛出异常的基本原因

更新

catch()
中的
function()
没有被执行的原因是
xxxError
不是
Exception
,所以你的
catch
不会捕获它——在中声明
catch(Throwable)
catch(Error)
function()
如果您不想声明所有特定错误 - 请注意,这通常是一个坏主意(您打算用
OutOfMemoryError
来做什么?.


4
投票

无法用

UnsatisfiedLinkError
捕获
Exception
的一个原因是
UnsatisfiedLinkError
不是
Exception
的子类。事实上,它是
Error
的子类。

您应该小心捕获 Error 异常。它们几乎总是表明发生了非常糟糕的事情,并且在大多数情况下不可能安全地从中恢复。例如,

UnsatisfiedLinkError
意味着 JVM 找不到本机库……并且依赖于该库的任何内容(可能)都无法使用。一般来说。
Error
异常应被视为致命错误。


0
投票

MethodInvocationException
意味着您调用了错误的方法,它甚至不应该进入您的 try 块内。来自文档:

Signals that the method with the specified signature could not be invoked with the provided arguments.

编辑:如果这是 Spring MethodInvokationException,那么 Apache Velocity 确实会包装函数异常。


0
投票

您像平常一样抛出异常。事实上它位于调用内部并没有什么区别。

public class B {
    public static void function() {
        try {
            throw new Exception();
        } catch (Exception e) {
            System.err.println("Caught normally");
            e.printStackTrace();
        }
    }

    public static void main(String... args) throws NoSuchMethodException, IllegalAccessException {
        Method method = B.class.getMethod("function");
        Object callTarget = null;
        try {
            method.invoke(callTarget, args);
        } catch (InvocationTargetException e) {
            // should never get called.
            throw new AssertionError(e);
        }
    }
}

打印

Caught normally
java.lang.Exception
at B.function(B.java:15)
... deleted ...
at B.main(B.java:26)
... deleted ...

0
投票

按照阿提拉的提示,我最终这样做了:

void function() {
  try {
    method.invoke(callTarget, args);
    
  }
  catch( Throwable e ) {
    Throwable throwEx = e.getCause();
    assertEquals("expectedErrorMessage", e.getCause().getMessage()); 
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.