使用NullPointerException测试null是不好的风格?

时间:2011-01-24 03:48:35

标签: java coding-style nullpointerexception

我有以下模式的代码:

return a().b().c().d().e();

现在由于这些方法中的每一个都可以返回null,因此通常会对此进行测试:

if( (a()!=null) && (a().b() != null) && ....) {
   return a().b().c().d().e();
} else  {
  return null;
}

(也许可以使用一些局部变量来避免重复调用)

我很想做:

try {
   return a().b().c().d().e();
} catch (NullPointerException e) {
   return null;
}

那被认为是不好的风格吗?效率低下?还是挺好的?

6 个答案:

答案 0 :(得分:16)

不要这样做。与基本空检查相比,抛出和捕获异常相当昂贵。

您可能也有兴趣知道已经为未来版本的Java提出了语法,这将使这更简单。它会是这样的:

a()?.b()?.c()?.d()

“?”操作将是“。”的可选版本。运营商。如果LHS为null,则在该点返回null,而不是尝试评估RHS。正是你在寻找什么,但我担心它没有为Java 7做好准备。不知道Java 8的这个功能的状态。

答案 1 :(得分:5)

它被认为是不好的风格,因为异常应该代表异常条件,这些条件在正常执行期间不太可能出现并且表明出现了问题。使用异常检查对象是否为null使用此机制来检查更平凡的故障。正如康斯坦丁的帖子所提到的,使用异常也会有运行时间损失。此外,将所有错误包装在一个NullPointerException中意味着您丢失了有关特别是错误的信息。哪个函数返回null?这是由于正常错误,还是有更严重的事情发生?

此处您还没有考虑其他选项。而不是让a()b(),等返回null来表示错误,请考虑让他们抛出更详细的异常,解释为什么他们无法返回某些内容。如果由于网络连接中断而导致它们失败,请让它们抛出IOException或类似内容。如果他们因为你的数组索引错误而失败,那么也要明确。

简而言之,如果您想使用异常,请使用它们来更精确地通知程序的其余部分发生了什么。这样,您可以采取更细粒度的纠正措施。

答案 2 :(得分:5)

通常,这行代码本身就很糟糕,忽略了null问题。请参阅"Law of Demeter" or "Principle of Least Knowledge"

return a().b().c().d().e();

如果我无法控制a,b,c,d和e,我会重写以下内容。

if( (a()!=null) && (a().b() != null) && ....) {
   return a().b().c().d().e();
} else  {
  return null;
}

就像这样,这仍然令人发指,但是当某些东西混乱并且我需要读取堆栈跟踪时更有用。

B b = a.a();
if(b == null)
{
   return null;
}

C c = b.b();
if(c == null)
{
   return null;
}

D d = c.c();
if(d == null)
{
   return null;
}

return d.d();

不,抓住NullPointerException并不恰当。这有点像在for块中包裹try循环以捕获ArrayIndexOutOfBoundsException

如果这应该是fluent API,其中链接是一个强度和目标,那么它永远不应该返回空值。

答案 3 :(得分:2)

我不这样做主要是因为如果a()b()c()等有一个导致它们抛出NullPointerException的错误?在那种情况下,你会抓住它并继续前进,而你却不应该这样做。

答案 4 :(得分:2)

更改方法,使它们不返回null或避免链接可返回null的方法。

答案 5 :(得分:1)

不是返回 null ,而是让每个人返回NullObject或其他东西。阅读Null Object Pattern