Java 使用NullPointerException测试null是否不好?

Java 使用NullPointerException测试null是否不好?,java,coding-style,nullpointerexception,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(

我有一些代码遵循以下模式:

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;
}

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

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

您可能还想知道,已经为Java的未来版本提出了语法,这将使它变得更简单。事情会是这样的:

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

“.”操作将是“.”运算符的可选版本。如果LHS为null,它将在该点返回null,而不是尝试计算RHS。这正是你想要的,但我担心它没有被Java7所接受。不知道Java 8的此功能的状态。

与其返回null,不如让它们各自返回null对象或其他内容。了解

我不会这么做,主要是因为如果
a()
b()
c()
等有一个导致他们抛出NullPointerException的错误怎么办?在这种情况下,您将捕获它,并在不应该的情况下继续前进。

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

这被认为是错误的样式,因为异常被认为代表异常情况,在正常执行过程中不太可能出现的事情,表明出现了问题。使用异常检查对象是否为null使用此机制检查更常见的故障。正如Konstantin的文章所提到的,使用异常也会受到运行时惩罚。此外,将所有错误包装在一个
NullPointerException
中意味着您将丢失有关具体错误的信息。哪个函数返回的
null
?这是由于正常的错误,还是发生了更严重的事情

这里还有其他您没有考虑的选项。而不是使用<代码>()< <代码> > <代码>(),<代码> >返回<代码> null <代码>以发出错误,考虑让它们抛出更详细的异常来解释为什么不能返回某些东西。如果他们因为网络连接中断而失败,让他们抛出
IOException
s或类似的东西。如果它们失败是因为数组中的索引不正确,那么也要说明这一点


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

一般来说,这行代码本身就不好,忽略了空问题。看

如果我不能控制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
循环包装在
中,尝试
块以捕获
ArrayIndexOutOfBoundsException


如果这是一个链接是一个优势和目标的地方,那么它永远不会返回Null。

虽然Null对象可能有用,但它可能隐藏一些问题,并使调试更加困难。如果唯一的好处是在一个地方省下几次测试,不要使用它。但是,如果他这样做是通过尝试捕捉。。。所以,不管怎样,它会起作用的,你知道。为什么我们不应该使用编程语言的特性呢?而且,是的,也许通过空检查来检查它会快一点,但是:不管怎样,如果速度不重要的话…@Martijn Courtaux:问题不在于捕捉NPE是否有效。显然是这样。问题在于养成这样编写代码的习惯是否是个好主意。不是。我大体上同意,但您并不总是有选择的余地,例如在使用第三方库时。另一种经常发生这种情况的情况是在对象关系数据库映射中,例如:resultSet.getFirst().getPerson().getBusinessUnit().getAddress().getPostCode();如果DB模式允许非常部分的信息,这种情况可能会发生很多。+1对于arrayindexoutofbounds比较,这是正确的。我认为使用异常来控制流是不好的。
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();