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

发布于 2024-07-17 21:11:41 字数 902 浏览 3 评论 0原文

我有一个线程,在一个大的、包罗万象的 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 - 这些控制台语句后面的内容并不重要。

I have a thread in which I catch all errors in a big, all-encompassing catch block. I do this so that I can report any error, not just expected ones, in my application. My Runnable looks like this:

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] */
    }
}

I would expect the NPE to be caught by the Throwable catch block. Instead, the output at [2] is not printed, and neither is [3]. The output at [1] is printed.

What I do get on the console, is this:

Uncaught exception java/lang/NullPointerException.

What on earth is going on here?

For the court records, I'm using J2ME, and this is running in Sun's WTK v2.5.2 emulator.

I'm tempted to put it down to JVM implementation dodginess but I can't help feeling that I'm just missing something.

To clarify for the avoidance of doubt (Since the example code is obviously altered from my production code)

  • There is nothing outside of the try/catch/finally block in the run method.
  • There is a System.out.println at the start of each of those blocks - What follows those console statements should not matter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

铜锣湾横着走 2024-07-24 21:11:41

答案证明我是个白痴。 我会解释出了什么问题,但我们姑且称之为“其中一个错误”。

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

canWait 方法是导致失败的原因,而 run 根本没有失败。 最重要的是,我有控制台失明,并且完全但意外地错误引用了我的问题中的事件顺序。

The answer turns out that I'm an idiot. I'd explain what went wrong, but let's just call it "one of those bugs".

I had momentarily forgotten that the thread that ran the runnable was a custom thread class (To get round some Nokia bugs). It called run() repeatedly between calls to a canWait() method.

The canWait method was responsible for the failure, and run wasn't failing at all. To top it off, I have console-blindness and completely but accidentally misquoted the sequence of events in my question.

鹿! 2024-07-24 21:11:41

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

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 块内。

Sounds like you'll need some trial and error. May I suggest:

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

By having an explicit catch for NullPointerException, it should become obvious if the exception is from within the try block or a catch/finally block.

羁客 2024-07-24 21:11:41

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

显然你的代码实际上不是这样的 - 所以我的猜测是你的 catch(或finally)块要么在记录任何内容之前执行某些操作,要么使用不同的记录器比 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 块实际走了多远吗?

Okay, this is a wild guess... but it would explain things.

Obviously your code isn't actually that - so my guess is that your catch (or finally) block is either doing something before it logs anything, or it uses a different logger than the try block. Either way, I suspect that either the catch or the finally block is throwing the exception.

I don't suppose you have a stack trace...

EDIT: Okay, if it's just System.out.println, is it something in the argument that might go bang? For example:

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

If it's just simple System.out.println("Constant") then it's very weird.

Do you know (e.g. from log lines within the try block) how far the try block is actually getting?

亽野灬性zι浪 2024-07-24 21:11:41

当我查看您的代码时,似乎recover() 抛出了异常,因此 Jon 给出的建议非常值得遵循。

如果您向我们提供了堆栈跟踪,您可能会得到更好的帮助。

当我尝试捕获异常时,我会这样做:

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

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

When I looked at your code it seems that recover() is throwing an exception, so the advice given by Jon would be excellent to follow.

If you gave us a stack trace you may get better help.

When I try to catch exceptions I do something like this:

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

I don't like to nest exceptions, but I don't like my catch block throwing exceptions.

香橙ぽ 2024-07-24 21:11:41

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

As you mention you are using a Runnable - does this by any chance mean that you are using multiple threads as well? If the doUnsafeThings() method internally spawns a different thread again and that produces the exception, you might not get it in the thread your catch block is.
See http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html

新雨望断虹 2024-07-24 21:11:41

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

It is generally a bad practice to catch NullPointerException.

Programmers typically catch NullPointerException under three circumstances:

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. 

Of these three circumstances, only the last is acceptable. following this link:

Catch NullPointerException

铜锣湾横着走 2024-07-24 21:11:41

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

Is it possible that the thread is being killed by some other code? In general a finally block always executes unless the thread is abnormally terminated, either by System.exit() or something similar.

一影成城 2024-07-24 21:11:41
  • 您确定您正在查看代码中的正确位置吗?
    即,您要保护的 doUnsafeThings() 块是否位于堆栈跟踪中?

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

  • Are you sure you are looking at the right place in the code?
    I.e., is the doUnsafeThings() block you are protecting in of the stack trace?

  • Maybe there is a problem with your build method, and you are debugging an old version of the code?

少女的英雄梦 2024-07-24 21:11:41

只需在 doUnsafeThings() 中添加一些日志记录即可; 看看该方法是否按照您的预期执行(例如,最后放置一个 try catch 并记录一些内容)

just add some logging in the doUnsafeThings(); to see if that method is doing what you expect (e.g put a try catch finally and log something)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文