Java:何时跳过对象的空检查?

Har*_*hit 9 java null object nullpointerexception

我在Java代码中使用了很多防御性空检查.虽然他们很好地服务于他们的目的(大部分时间),但他们的代码与"丑陋"的代码有很大关系.

将这些空检查始终放入是否真的有意义?例如:

if(object == null){
  log.error("...")
  throw new SomeRuntimeException("");
} else{
  object.someMethod();
}
Run Code Online (Sandbox Code Playgroud)

实际上,上面的代码相当于声明 object.someMethod();

如果object的值为null,则在两种情况下都会抛出异常(后面的NullpointerException).

掩码NullpointerExcetion(NPE)并抛出一些自定义RunTimeException(如上面的代码片段)真的有意义吗?我观察到一些开发人员将NPE视为邪恶,经常试图找出掩盖它的防御方法并用一些自定义异常掩盖它.这种掩蔽真的需要吗?

  1. 如果我们无法从该null状态恢复,那么允许我们的代码通过NPE失败是否有意义?(在上面的例子中,它似乎是一个不可恢复的场景.)
  2. 如果没有,为什么?

ysh*_*vit 8

在您发布的情况下,支票没有任何好处.你将一个RuntimeException替换为另一个没有额外信息或价值的RuntimeException(对于不熟悉你的代码的人来说可能一点,因为每个人都知道NPE是什么,并不是每个人都知道你的SomeRuntimeException是什么).

我考虑明确检查的主要两次是:

  1. 当我想抛出一个已检查的异常而不是未选中时.
  2. 当我想在实际使用引用之前检查null.

第二种情况尤其重要,因为我只是为了以后存储引用:例如,在构造函数中.在这种情况下,当有人使用引用并触发NPE时,可能很难找到那个null的位置.通过在将其保存到字段之前检查它,您更有可能找到根本原因.实际上,这是一个常见的模式,JDK甚至可以requireNonNull为它提供帮助.

如果你看一下很多成熟的,高信誉的项目,我想你会发现"只是使用它,如果它发生就让NPE发生"模式很常见.举一个例子,JDK的代码Collections.sort很简单list.sort(null),list方法参数在哪里.如果它为null,那么该行将抛出一个NPE.