什么时候可以捕获NullPointerException? [英] When is it OK to catch NullPointerException?

查看:455
本文介绍了什么时候可以捕获NullPointerException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有效的java建议我们不要 catch NullPointerException
它总是正确吗?

Effective java recommends that we shouldn't catch NullPointerException. Is it always right?

在很多情况下捕获 NullPointerException ,catch body只调用 printStackTrace()

In many cases of catching NullPointerException, catch body only calls printStackTrace().

如果我没有捕获 NullPointerException 并调用 printStackTrace(),我如何检查异常发生的地方?

If I don't catch NullPointerException and call printStackTrace(), how I can check the place where the exception occurred?

如果我抓住 NullPointerException 并且 catch 正文为空,我们无法获取当时的任何堆栈信息,我们可以吗?

And also if I catch NullPointerException and the catch body is empty, we cannot get any stack information at that time, can we?

更新

我分析了在google android source中捕获RuntimeException的统计信息,AOSP4.2.2_r1.2。

I analyzed statistics of catching RuntimeException in google android source, AOSP4.2.2_r1.2.

有249个RuntimeException捕获,以下是catch-body的统计信息。

There are 249 RuntimeException catchings and followings are statistics of catch-body.

42%: throw it again as other Exceptions (RuntimeException: 33%, others: 8%)

32%: just return null or 0/false/true or other default values

14%: just call log or printstacktrace

5%: just comment like "// Fall through.", "// ignore, not a valid type.", "// system process dead", "// do nothing"

2%: empty body

3%: display error messages or send fail codes (ex. network service discovery failed: replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, NsdManager.FAILURE_INTERNAL_ERROR); )


3%: intialize or reset related variables.

在大多数情况下,dalvik和外部通过抛出其他例外来处理NPE。

In almost cases, dalvik and external handle NPE by throwing other Exceptions.

但框架通常通过返回null或其他值来处理。

But frameworks usually handle by returning null or other values.


  1. 你认为抛出其他catch-body中的例外情况不错或处理不当?

  1. Do you think that throwing other Exceptions in catch-body is not bad or good handling?

如果NPE出现在更高级别(例如应用程序)并且开发人员确认异常并不重要因为应用程序是完全独立的,我可以接受让我们的开发人员通过捕获来忽略NPE吗?

If NPE occured in higher levels(ex. applications) and the developer confirms the exception is not critical because the app is fully independent, can I accept for our developer to ignore the NPE by catching?

还有一个事情,

我可以得出结论,谷歌android框架源代码在 RuntimeException 方面可能会有些不稳定吗?

Can I conclude that google android framework source code may be some unstable in aspects of RuntimeException?

推荐答案


有效的java建议我们不要捕获NullPointerException。总是正确吗?

Effective java recommend that we shouldn't catch NullPointerException. Is it always right?

几乎在所有情况下都是正确的。

In nearly all cases it is correct.

NullPointerException 通常是一个错误的结果;即,您的应用程序在未预料到的情况下遇到 null 对象引用,然后尝试使用它。在这种情况下,由于您(程序员)没有预料到 null ,因此几乎无法知道尝试是否安全恢复,和/或知道可能需要什么补救。因此,最好的办法是让NPE传播到基本级别,然后将其视为通用错误。 (在网络服务应用程序中,可能适合返回服务错误响应,并尝试继续。)

NullPointerException is usually a result of a bug; i.e. your application encountered a null object reference in a situation where it was not anticipated, and then attempted to use it. In this scenario, since you (the programmer) did not anticipate the null, it is next to impossible to know whether it is safe to attempt to recover, and / or to know what "remediation" might be required. So the best thing to do is to let the NPE propagate to the base level, and then treat it as a generic bug. (In "network service" applications, it may be appropriate to return a "service error" response, and attempt to continue.)

另一种情况是你(程序员)预计可能会传递 null 。在这种情况下,最好的策略是(几乎总是)在尝试使用之前显式测试 null ,从而避免 NPE ......以及处理它的需要。这有两个原因:

The other scenario is where you (the programmer) anticipate that a null might be delivered. In this case, the best strategy is (nearly always) to explicitly test for the null before you attempt to use it, thereby avoiding the NPE ... and the need to handle it. There are two reasons for this:


  • 异常处理通常很昂贵。实际上,它比 null 的测试更加许多数量级

如果您允许预期的NPE发生然后捕获它,您也可能会捕获其他意外的 NPE ......并且错误地处理它们。

If you allow the expected NPE to happen and then catch it, you are liable to also catch other unexpected NPEs ... and handle them incorrectly.

请注意,我通过说几乎总是来证明上述条件。从理论上讲,有一种场景可以对 null 进行显式测试,使代码混乱到至少值得考虑允许NPE发生。但是,仍然存在意外的NPE的可能性......取决于代码。所以这种方法总是可能脆弱。

Note that I qualified the above by saying "nearly always". It is theoretically possible to have a scenario where explicit tests for null clutter up your code so much that it is at least worth considering allowing the NPE to happen. However, there is still the possibility of unexpected NPEs as well ... depending on the code. So this approach is always potentially fragile.

(FWIW - 我从来没有遇到过这个好主意的真实案例......)

(FWIW - I've never encountered a real case where this would be a good idea ...)

在捕捉的NullPointerException的许多情况下,卡位体仅调用的printStackTrace()。

In many cases of catching NullPointerException, catch body only calls printStackTrace().

这可能是错误的代码。无为是很少从一个NPE恢复的正确方法。

That is probably bad code. Doing nothing is rarely the correct way to recover from an NPE.

如果我不明白NullPointerException异常和调用的printStackTrace(),我怎么可以检查发生异常的地方吗?

If I don't catch NullPointerException and call printStackTrace(), how I can check the place where the exception occurred?

您让NPE传播到基准级别。在那里你捕获并打印(或记录)所有未处理异常的堆栈跟踪,然后挽救或尝试恢复......如果这是可行的。

You let the NPE propagate to the base level. There you catch and print (or log) a stacktrace for all unhandled exceptions, and then either bail out or attempt to recover ... if that is feasible.


如果我捕获NullPointerException并且catch体为空,那么我们当时无法获取任何堆栈信息,是吗?

And also if I catch NullPointerException and the catch body is empty, we cannot get any stack information at that time, can we?

永远不要这样做!它被称为挤压并且危险。 (特别是因为,正如我上面所解释的那样,NPE可能是由于你/你的代码没有预料到的。)

Never, ever do this! It is called "squashing" and is dangerous. (Especially since, as I explained above, the NPE may be due to something that you / your code did not anticipate.)

不,如果你这样做,你就是无法获得堆栈跟踪。它消失了。

And no, if you do this, you can't get the stack trace. It is gone.

关注

我对避免NPEs 1 的一些一般策略没有太多的信任/信心。比如这样的东西:

I don't place much trust / faith on some general strategies for "avoiding NPEs"1. For instance stuff like this:

return (someObject != null) ? someObject.toString() : "";

总是让我怀疑程序员没有考虑问题。为什么首先 someObject a null

always make me suspicious that the programmer is not thinking about the problem. Why was someObject a null in the first place?

NPE是由于 null 在您不期望的地方造成的。因此,NPE通常是问题的症状而不是实际问题本身。在我看来,NPE不是一个值得避免的东西。相反,您应该使用NPE来查找并修复意外 null 根本原因。像上面那样避免NPE的代码妨碍了这个目标。

A NPE is caused by having a null in place where you don't expect it. As such, NPEs are usually symptoms of a problem rather than the actual problem itself. To my mind, NPEs are not something to be avoided. Rather, you should be using the NPEs to find and fix the root cause of the unexpected null. Code like the above that avoids the NPE gets in the way of that goal.

所以我更喜欢/推荐避免 null的策略意外地点的值。

So I prefer / recommend strategies for avoiding null values in unexpected places.


  • 确保每个参考字段都被初始化为非空值。 。除非 null 有意义的值。

尽量避免 null 作为有意义的值,尤其是在有替代值的情况下。例如,一个空字符串,一个零长度数组,一个空集合,一个表示未定义或其他的可分辨实例。或者,对于Java 8及更高版本,请使用可选

Try to avoid having null as a meaningful value, especially if there is an alternative. For instance, an empty String, a zero length array, an empty collection, a distinguished instance that means "undefined" or whatever. Or, for Java 8 and later, use Optional.

不要返回 null 作为错误或特殊情况的指示。 (抛出异常或返回一个不同的值。)

Don't return null as an error or an indication of a special case. (Throw an exception or return a distinguished value.)

提前检查未预料到的 null 值(例如 null arguments),并尽快抛出NPE

Check early for unanticipated null values (e.g. null arguments), and throw the NPE sooner rather than later.

null 参数或结果合法的少数几个地方,请确保您的javadocs清楚明确地记录了这一点。如果没有文档,那么暗示应该是 null 是不允许的,不会被返回。

In the few places where a null argument or result is legitimate, make sure that your javadocs document this clearly and explicitly. If there is no documentation, then the implication should be that null is not allowed and won't be returned.

无论你在哪里获得NPE,请确保找到并修复问题的真实来源...而不仅仅是抛出的具体陈述例外。

And wherever you get an NPE, make sure that you find and fix the real source of the problem ... not just the specific statement that threw the exception.

1 - 了解标准Java API中的位置有价值,其中 null 被用作(或滥用)作为返回值。例如, Class.getResourceAsStream(...) HttpRequest.getParam(...)。那些避免NPE的建议文件在指出这些陷阱方面非常有用。

1 - There is value in knowing about places in the standard Java APIs where null is used (or abused) as a return value. For instance, Class.getResourceAsStream(...) or HttpRequest.getParam(...). Those "advice for avoiding NPE" documents are useful in as much that they point out these traps.

这篇关于什么时候可以捕获NullPointerException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆