gpt4 book ai didi

java - 什么时候可以捕获NullPointerException?

转载 作者:太空狗 更新时间:2023-10-29 22:48:56 25 4
gpt4 key购买 nike

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

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

如果我没有 catch 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或其他值来进行处理。
  • 您认为在catch-body中抛出其他异常不是不好还是很好的处理?
  • 如果NPE发生在较高级别(例如应用程序)中,并且开发人员确认异常不是至关重要的(因为该应用程序是完全独立的),我是否可以接受我们的开发人员通过捕获忽略NPE?

  • 还有一件事,

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

    最佳答案

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



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

    另一种情况是您(程序员)期望传递 null。在这种情况下,最好的策略是(几乎总是)在尝试使用 null之前对其进行显式测试,从而避免了NPE ...以及处理它的需要。有两个原因:
  • 异常处理通常很昂贵。实际上,与测试null相比,它的成本可能高出多个数量级。
  • 如果您允许预期的NPE发生然后捕获它,您还可能会捕获其他意外的NPE ...并错误地处理它们。


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

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

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



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

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



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

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



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

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

    FOLLOWUP

    我对“规避NPE” 1的一些一般策略没有太多信任/信念。例如这样的东西:
    return (someObject != null) ? someObject.toString() : "";

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

    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的建议”文档在指出这些陷阱方面非常有用。

    关于java - 什么时候可以捕获NullPointerException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18265940/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com