我该如何捕获NoSuchMethodException?

6

我依赖的代码发生了一些不兼容的更改。因此,我想捕获NoSuchMethodException以记录有关问题的更多信息。

当我使用以下内容时:

try{
     do.something();      
}catch(NoSuchMethodException e){
     System.out.println("!");
}

我遇到了这个错误:“NoSuchMethodException的catch块无法访问。该异常从try语句体中永远不会抛出。”
我尝试捕获java.lang.RuntimeException并检查是否为NoSuchMethod,但没有成功。
反射会导致性能延迟,我不想使用它...
有什么建议吗?

你的 do.something() 实际上是做什么的? - Saher Ahwal
2
捕获RuntimeException失败,因为NoSuchMethodException不是RuntimeException的子类。 - Andrew Fielden
7个回答

9

您可能会混淆NoSuchMethodException和NoSuchMethodError,前者仅在使用反射调用不存在的方法时抛出,而后者可能在直接调用存在于编译时但在运行时不存在的方法时抛出。这通常发生在编译时和运行时使用不同版本的某些外部库时。

底线:捕获NoSuchMethodError


5
捕获 NoSuchMethodError 错误。但是这似乎是一个不好的解决方法,我建议解决不兼容性问题。

没错。在一个类中调用一个已经没有定义的方法会产生一个错误,而不是异常。 - Ted Hopp
所抛出的错误/异常类型将取决于代码试图执行的操作。当代码尝试调用无效方法时,会出现NoSuchMethodError。而如果代码尝试为不存在的方法调用getMethod(),则会抛出NoSuchMethodException。 - Andrew Fielden

2
编辑: 这是如何声明已检查异常的通用解决方案。正如其他人所指出的那样,你应该捕获NoSuchMethodError甚至IncompatibleClassChangeError ,因为这是在运行时抛出的内容。

由于你想链接到一个不同于编译版本的库(本身不建议这样做,但我不想评判),你需要说服编译器一切都很顺利。

在这种情况下,一种方法是创建一个静态助手来声明异常:

class Util {
    public static void unsafeApiCall() throws NoSuchMethodException {
        // if (false) prevents a compilation error
        if (false) throw new NoSuchMethodException();
    };
}

使用方法

try {
    Util.unsafeApiCall();
    do.something();      
} catch(NoSuchMethodException e2) {
    System.out.println("!");
}

这也在视觉上脱颖而出,这是一件好事。


EDIT2: 如果您在不声明的情况下抛出已检查的异常,则可能需要这样做,如此处所述。


1

NoSuchMethod应该意味着你试图访问一个不存在的方法,可能是在运行时。最好的做法是修复它,而不是尝试捕获异常。

将方法放在它应该在的位置上会更好,这样你就不会有逻辑错误,如错误的输出等。


1

我建议您查看@matt b的答案。使用NoSuchMethodError。

但是,如果您确实想要捕获NoSuchMethodException,您将不得不明确地使用以下方法抛出它:

throw new NoSuchMethodException();

1
无法访问 NoSuchMethodException 的 catch 块。这个异常从 try 语句体中永远不会被抛出。
正如 IDE/编译器所说,在 try 语句体中,从未抛出 NoSuchMethodException。这意味着您调用的方法中没有一个声明为:
public void doSomething() throws NoSuchMethodException

在 try 代码块中从未抛出过 NoSuchMethodException 异常:

throw new NoSuchMethodException();

0
首先,我强烈反对那些告诉你要捕获错误的人。不要这样做。错误应该被留给应用程序范围的异常处理程序来处理。如果你的应用程序这样做了,那么你只需要在日志文件中搜索就可以得到你不兼容的证据。
另外,在使用反射判断代码之前,不要轻易下结论,直到你对其进行了剖析并确定了它所需的时间。通常关于减速点在哪里的猜测最终都是错误的。在你测量并证明它是一个瓶颈之前,你永远不应该优化任何东西。
深入挖掘do.something代码,如果没有源代码,则对其进行反编译,并查看实际抛出的内容。可能,如果异常被抛出,它可能会被包装在另一个异常中。确保方法抛出的任何内容都不会被吞噬(包括你自己记录的内容)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接