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

时间:2009-04-22 11:32:07

标签: java exception java-me try-catch java-wireless-toolkit

我有一个线程,我可以在一个大而全方位的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 - 这些控制台语句后面的内容应该不重要。

9 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:5)

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

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,如果异常来自try块或catch / finally块,则应该很明显。

答案 2 :(得分:4)

好的,这是一个疯狂的猜测...但它可以解释事情。

显然你的代码实际上不是 - 所以我的猜测是你的catch(或者最后)块在记录任何内容之前要做某事,它使用与try块不同的记录器。无论哪种方式,我怀疑catch或finally块都抛出异常。

我认为你没有堆栈跟踪......

编辑:好的,如果它只是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块实际到达了多远?

答案 3 :(得分:2)

当我查看你的代码时,似乎recover()正在抛出一个异常,因此Jon提供的建议非常适合。

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

当我尝试捕捉异常时,我会做这样的事情:

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

我不喜欢嵌套异常,但我不喜欢我的catch阻止抛出异常。

答案 4 :(得分:2)

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

答案 5 :(得分:1)

捕获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. 

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

Catch NullPointerException

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

  • 您的构建方法可能存在问题,而您正在调试旧版本的代码?

答案 8 :(得分:0)

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