java 捕捉null异常_java – 什么时候可以捕获NullPointerException?

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

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

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

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

>异常处理通常很昂贵.实际上,它比测试零点要贵许多个数量级.

>如果您允许预期的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可能是由于你/你的代码没有预料到的.)

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

跟进

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

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

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

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

所以我更喜欢/建议在意外的地方避免空值的策略.

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

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

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

>提前检查未预料到的空值(例如空参数),并尽快抛出NPE.

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

无论你在哪里获得NPE,都要确保找到并修复问题的真正根源……而不仅仅是抛出异常的特定语句.

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值