当前位置: 首页 > 面试题库 >

什么时候可以捕获NullPointerException?

云霖
2023-03-14
问题内容

有效的Java建议我们不要这样做catch NullPointerException。总是对的吗?

在许多情况下,NullPointerException仅捕获身体printStackTrace()

如果我不NullPointerException接听电话printStackTrace(),如何检查exception发生的地点?

而且,如果我抓住NullPointerException了但catch身体空了,那我们那时就无法获得任何堆栈信息,可以吗?

更新

我分析了在Google Android源AOSP4.2.2_r1.2中捕获RuntimeException的统计信息。

有249个RuntimeException捕获,并且以下是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。

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

  1. 您认为在catch-body中抛出其他异常不是不好还是很好的处理?

  2. 如果NPE发生在较高级别(例如应用程序)中,并且开发人员确认异常不是至关重要的(因为该应用程序是完全独立的),我是否可以接受我们的开发人员通过捕获忽略NPE?

还有一件事情,

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


问题答案:

有效的Java建议我们不要捕获NullPointerException。总是对的吗?

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

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

另一种情况是您(程序员)期望null交付a。在这种情况下,最好的策略是(几乎总是)null 尝试使用它 之前 进行显式测试,从而
避免 了NPE …以及处理它的需要。有两个原因:

  • 异常处理通常很昂贵。的确,这可能比测试一个版本昂贵 许多数量级null

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

请注意,我通过说“几乎总是”来限定以上条件。从理论上讲,有可能发生显式测试使null代码混乱的情况,至少值得 考虑
让NPE发生。但是,仍然存在意外的NPE的可能性,具体取决于代码。因此,这种方法始终是 潜在的 脆弱。

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

在捕获NullPointerException的许多情况下,catch主体仅调用printStackTrace()。

那可能是错误的代码。无所事事很少是从NPE恢复的正确方法。

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

您让NPE传播到基本级别。在那里,您捕获并打印(或记录) 所有 未处理的异常的堆栈跟踪,然后纾困或尝试恢复……如果可行的话。

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

永远不要这样做!它被称为“挤压”,很 危险 。(特别是因为如上所述,NPE可能是由于您/您的代码未曾预料到的。)

不,如果执行此操作,则无法获取堆栈跟踪。没了

跟进

我对“规避NPE” 1的一些一般策略没有太多信任/信念。例如这样的东西:

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

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

NPE是由null您不期望的地方引起的。因此,NPE通常是问题的 征兆
,而不是实际问题本身。在我看来,NPE不可避免。相反,您应该使用NPE来查找和修复意外事件的
根本原因null。像上面这样的代码可以避免NPE阻碍该目标的实现。

因此,我更喜欢/推荐一些避免null在意料之外的地方采取措施的策略。

  • 确保将每个引用字段初始化为非空值…除非null有意义的 值。

  • 尽量避免具有null有意义的值,尤其是在有其他选择的情况下。例如,一个空的String,一个零长度的数组,一个空的集合,一个表示“未定义”的专有实例或其他。或者,对于Java 8及更高版本,请使用Optional

  • 不要null作为错误或特殊情况的指示返回。(引发异常或返回可分辨的值。)

  • 尽早检查意外null值(例如,null参数),并 尽早(而不是稍后 )抛出NPE 。

  • 在少数几个null参数或结果合法的地方,请确保您的javadocs清楚明确地记录了这一点。如果没有文档,则意味着null不允许这样做,也不会返回。

无论您在哪里获得NPE,都应确保找到并解决问题的 真正 根源……而不仅仅是引发异常的特定声明。

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



 类似资料:
  • 问题内容: 在最近的项目中,我建议在测试工具代码中捕获RuntimeException并将其记录下来。该代码处理来自数据库的一系列输入,并且我不希望由于任何一个输入(空值,非法参数等)失败而导致测试停止。不用说,我的建议引起了热烈的讨论。 捕获任何一种RuntimeException是否可以接受?如果是,那么可以捕获RuntimeExceptions的其他方案还有哪些? 问题答案: 捕获此异常的原

  • 我已经用Java编写代码一段时间了。但有时,我不知道什么时候应该抛出异常,什么时候应该捕获异常。我正在做一个有很多方法的项目。层次结构是这样的- 所以目前我正在做的是-我在所有方法中抛出异常并在方法A中捕获它,然后将其记录为错误。 但我不确定这是否是正确的方法?或者我应该开始在所有方法中捕获异常。这就是为什么这种混乱始于我的 - 我什么时候应该抓住异常与何时应该抛出异常。我知道这是一个愚蠢的问题,

  • 问题内容: 我从jls找到了报价: 相等运算符可用于比较两个可转换(第5.1.8节)为数字类型的操作数,或两个boolean或Boolean类型的操作数,或 两个分别为引用类型或null类型的操作数 。所有其他情况都会导致编译时错误。 但是这段代码 每个操作数都是参考! 说这是不兼容的类型。 jls在哪里说这些类型应该兼容? 问题答案: 在15.21.3节(参考相等运算符==和!=)中: 如果无法

  • 问题内容: 我正在开发JSON / REST Web API,为此,我特别希望第三方网站能够通过AJAX调用我的服务。因此,我的服务正在发送著名的CORS标头: 允许第三方站点通过AJAX调用我的服务。到目前为止一切都很好。 但是,我的Web api的一个子部分是非公开的,需要身份验证(带有OAuth和access_token cookie的相当标准的东西)。在我网站的此部分也启用CORS是否安全

  • 我找到了JLS引文: 表示它是不兼容的类型。 在jls中哪些地方说这些类型应该兼容?

  • 问题内容: 最近,我们在Java服务器应用程序中遇到了一个问题,该应用程序正在抛出未捕获的错误,因为Error是Throwable的一个单独的子类,而我们仅捕获了Exceptions。 我们通过捕获Throwables而不是Exceptions解决了眼前的问题,但这使我思考为什么您要捕获Exceptions而不是Throwables,因为您随后会错过Errors。 那么, 当您可以捕获Throwa