为什么我的NullPointerException没有被我的catch块捕获?

我有一个线程,我在一个大的,无所不包的catch块中捕获所有错误。 我这样做,以便我可以在我的应用程序中报告任何错误,而不仅仅是预期的错误。 我的Runnable看起来像这样:

public final void run() { try { System.out.println("Do things"); /* [1] */ doUnsafeThings(); } catch (Throwable t) { System.out.println("Catch"); /* [2] */ recover(); } finally { System.out.println("Finally"); /* [3] */ } } 

我希望NPE能被Throwable catch块捕获。 相反,不打印[2]处的输出,也不打印[3]。 打印[1]处的输出。

我在控制台上得到的是这样的:

 Uncaught exception java/lang/NullPointerException. 

到底是怎么回事?

对于法庭记录,我正在使用J2ME,这是在Sun的WTK v2.5.2模拟器中运行的。

我很想把它归结为JVM实现的笨拙,但我不禁感到我只是错过了一些东西。

澄清是为了避免怀疑(因为示例代码明显改变了我的生产代码)

  • run方法中try / catch / finally块之外没有任何内容。
  • 每个块的开头都有一个System.out.println – 这些控制台语句后面的内容应该无关紧要。

答案结果certificate我是个白痴。 我会解释出了什么问题,但让我们把它称为“其中一个错误”。

我暂时忘记了运行runnable的线程是一个自定义线程类(为了解决一些诺基亚漏洞)。 它在调用canWait()方法之间反复调用canWait()

canWait方法导致失败,并且运行根本没有失败。 最重要的是,我有控制台失明,完全但不小心错误地引用了我的问题中的事件序列。

听起来你需要一些试验和错误。 我可以建议:

 try { doEvilStuff(); } catch (NullPointerException ex) { System.out.println("NPE encountered in body"); } catch (Throwable ex) { System.out.println("Regular Throwable: " + ex.getMessage()); } finally { etc... } 

通过显式捕获NullPointerException,如果exception来自try块或catch / finally块,则应该很明显。

好吧,这是一个疯狂的猜测…但它会解释事情。

显然你的代码实际上并不是这样 – 所以我的猜测是你的catch(或者最后一个)块在记录任何东西之前要么做一些事情, 要么使用与try块不同的记录器。 无论哪种方式,我怀疑catch或finally块是否抛出exception。

我不认为你有堆栈跟踪…

编辑:好的,如果它只是System.out.println ,那么论证中的某些内容可能会爆炸吗? 例如:

 catch (Throwable t) { // Will go bang if t.getCause() returns null System.out.println(t.getCause().getMessage()); } 

如果它只是简单的System.out.println("Constant")那么它非常奇怪。

您是否知道(例如,来自try块中的日志行)try块实际得到了多少?

当我查看你的代码时,似乎recover()抛出exception,所以Jon提供的建议非常好。

如果你给我们一个堆栈跟踪,你可能会得到更好的帮助。

当我尝试捕获exception时,我会做这样的事情:

 try { doSomethingBad(); } catch(Exception e) { try { LogException(...); } catch(Exception e) {} } finally { } 

我不喜欢嵌套exception,但我不喜欢我的catch块抛出exception。

正如你所提到的,你正在使用Runnable – 这有可能意味着你也使用多个线程吗? 如果doUnsafeThings()方法在内部再次生成一个不同的线程并产生exception,则可能无法在catch块的线程中获取它。 请参阅http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html

捕获NullPointerException通常是一种不好的做法。

程序员通常在三种情况下捕获NullPointerException:

 The program contains a null pointer dereference. Catching the resulting exception was easier than fixing the underlying problem. The program explicitly throws a NullPointerException to signal an error condition. The code is part of a test harness that supplies unexpected input to the classes under test. 

在这三种情况中,只有最后一种是可以接受的。 点击此链接:

捕获NullPointerException

是否有可能该线程被其他一些代码杀死? 通常,finally块总是执行,除非线程被System.exit()或类似的东西exception终止。

  • 您确定要在代码中找到正确的位置吗? 即,你正在保护堆栈跟踪的doUnsafeThings()块吗?

  • 也许你的构建方法有问题,而你正在调试旧版本的代码?

只需在doUnsafeThings()中添加一些日志记录; 看看那个方法是否正在做你期望的事情(例如,最后尝试捕获并记录一些东西)