关于NPE和单线多表达式的最佳实践

时间:2010-06-03 14:16:40

标签: java nullpointerexception

我想知道,对于可能的NPE,是否避免在同一条线路上进行多次呼叫是否是公认的做法,如果是这样,在什么情况下。例如:

anObj.doThatWith(myObj.getThis());

VS

Object o = myObj.getThis();
anObj.doThatWith(o);

后者更冗长,但如果有NPE,你会立即知道null是什么。但是,它还需要为变量和更多import语句创建名称。

所以我的问题是:

  • 这个问题值得吗? 围绕设计?去吧更好 第一种或第二种可能性?
  • 变量名称的创建是否具有性能效果?
  • 是否有更改例外的提案 消息能够确定什么 在将来的版本中,对象是null Java?

5 个答案:

答案 0 :(得分:5)

  

这个问题值得设计吗?第一种或第二种可能性更好吗?

IMO,没有。转到最可读的代码版本。

如果您获得无法诊断的NPE ,则根据需要修改代码。或者,使用调试器运行它,并使用断点和单步执行来找出空指针的来源。

  

变量名称的创建是否会产生性能影响?

添加额外变量可能会增加堆栈帧大小,或者可能会延长某些对象保持可访问的时间。但这两种影响都不大可能。

  

是否有建议更改异常消息,以便能够在将来的Java版本中确定哪个对象为null?

不是我知道的。实现这样的功能可能会带来显着的性能下降。

答案 1 :(得分:2)

Law of Demeter明确表示根本不这样做。

答案 2 :(得分:2)

如果您确定getThis()无法返回null值,则可以使用第一个版本。您可以在代码中使用合同注释来检查这些条件。例如,Parasoft JTest使用类似@post $result != null的注释,并标记所有方法,而不使用返回值而不进行检查的注释。

如果方法可以返回null,则代码应始终使用第二个变量,并检查返回值。 只有您可以决定如果返回值为null该怎么办,可能没问题,或者您可能想要记录错误:

Object o = getThis();

if (null == o) {
    log.error("mymethod: Could not retrieve this");
} else {
    o.doThat();
}

答案 3 :(得分:0)

就个人而言,我不喜欢单行代码“设计模式”,所以我支持所有那些保持代码可读性的人。虽然我在现有项目中看到了与此类似的更糟糕的代码行:

someMap.put(
     someObject.getSomeThing().getSomeOtherThing().getKey(),
     someObject.getSomeThing().getSomeOtherThing()) 

我认为没有人会认为这不是编写可维护代码的方法。

至于使用注释 - 遗憾的是并非所有开发人员都使用相同的IDE,而Eclipse用户也无法从 @Nullable @NotNull <中受益/ em> 注释。如果没有IDE集成,这些没有太多好处(除了一些额外的文档)。不过我建议使用 assert 。虽然它只在运行期间有所帮助,但它确实有助于找到大多数NPE原因并且没有性能影响,并使您的代码更清晰的假设。

答案 4 :(得分:0)

如果是我,我会将代码更改为后一版本,但我也会添加日志(可能是print)语句和log4j这样的框架,所以如果出错了我可以检查日志文件以查看什么是null。