我如何捕获NoSuchMethodException?

时间:2011-07-26 15:47:34

标签: java exception exception-handling

我依赖的代码中存在一些不兼容的更改。 所以我想捕获NoSuchMethodException以记录有关问题的更多信息

当我使用它时:

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

我收到此错误“NoSuchMethodException的无法访问的catch块。此异常永远不会从try语句主体中抛出”

我也尝试捕获java.lang.RuntimeException并检查它是否为NoSuchMethod但它不起作用。

反射会导致性能延迟,并且不想使用它....

有什么想法吗?

7 个答案:

答案 0 :(得分:7)

只有在调用此方法在编译时存在并且在运行时不存在时直接调用方法时可能引发的反射和NoSuchMethodError引发的NoSuchMethodException时,您才会混淆NoSuchMethodException。通常在编译和运行时使用某些外部库的不同版本时会发生这种情况。

底线:抓住 NoSuchMethodError

答案 1 :(得分:5)

抓住NoSuchMethodError代替。然而,这似乎是一个丑陋的解决方法,我建议只是解决不兼容问题。

答案 2 :(得分:1)

NoSuchMethod应该意味着您尝试访问一个不存在的方法,可能是在运行时。如果您修复此问题而不是尝试捕获异常,则最好。

最好将方法置于其意图所在的位置,以便您不会出现错误输出等逻辑错误

答案 3 :(得分:1)

我建议你去@matt b的答案。使用NoSuchMethodError.

但是,如果您想要捕获NoSuchMethodException,则必须使用明确抛出它,

throw new NoSuchMethodException();

答案 4 :(得分:1)

  

NoSuchMethodException的无法访问的catch块。这个例外是   永远不会从try语句体中抛出

正如IDE /编译器所说。在try主体中,永远不会抛出NoSuchMethodException。这意味着您调用的所有方法都不会声明为:

public void doSomething() throws NoSuchMethodException

也从未在try体中抛出NoSuchMethodException

throw new NoSuchMethodException();

答案 5 :(得分:1)

编辑:这是如何声明已检查的例外的一般解决方案。正如其他人所指出的那样,你应该抓住 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 :正如here所描述的那样,如果你在没有声明它们的情况下抛出已检查的异常,那么这样的事情可能是无关紧要的。

答案 6 :(得分:1)

首先,我强烈反对所有告诉你捕捉错误的人。不要那样做。错误应该保持不变,以适应您的应用程序所具有的任何应用程序范围的异常处理程序。如果你的应用程序这样做,那么你需要做的就是获取不兼容的证据就是grep你的日志文件。

此外,在您对其进行分析并确切知道需要多长时间之前,请不要使用反射对代码进行判断。通常猜测减速最终会变得不正确。在进行测量并证明它是瓶颈之前,你不应该优化任何东西。

深入了解do.something代码,如果您没有源代码,则对其进行反编译,然后查看它实际抛出的内容。可能如果抛出异常,它可能会包含在另一个异常中。确保方法抛出的任何东西都不会被吃掉(包括你自己记录它)。