在Java中避免“!= null”语句?

来源:互联网 发布:java开发基础知识 编辑:程序博客网 时间:2024/06/05 05:07


原问题:

我整天都在用Java工作。在用Java编程时用的最多的语句(或者说代码片段),就是在使用一个对象前,我都会先测试object != null(对象是否为空)这是为了避免抛空指针(NullPointerException) 的错误。我发现这样代码一点都不美观,并且可读性不高。

有没有好的选择可以避免掉这段代码?

更新:潘(Pan,人名),我也不是太清楚自己的问题。我想强调的是,如果你想要访问某个对象的字段或方法,对这个对象是否为null的测试是必要的。例如:
 
...if (someobject != null) {     someobject.doCalc(); } ...

在这种情况下,我不必知道对象是否为null,就可以避免空指针(NullPointerException)的错误。但因此,我的代码里就会满是这种测试。
不过还是非常感谢你的回答,我又得到了一些新的见解。


票选最高回答:

对我来说,这是个相当普遍的问题,并且是从初级到中级开发人员往往都要面对的:他们要么是不知道,要么是不相信他们都在参与并过度检查来抵御null的出现 (这句真心是翻译残了,overcheck卡住我了。。。我只好理解成over check,希望有朋友指正) 。此外,在编写自己的代码时,他们往往依赖返回空值来指明(or 表示)一些东西,因此,这就需要调用者来检查空值(nulls)。

换种方式来说,当涉及到空值检查时会有两种情况:
  1. 空值是符合条件的有效响应;和
  2. 不是有效响应

第2种情况简单。要么用assert语句(断言)要么允许抛错(例如,NullPointerException空指针错误)Assertions是java1.4以后新增的一个没有被高度利用的java特性。语法如下:

        表达式1:assert *<condition>*
或者

        表达式2:assert *<condition>* : *<object>*


 <object>的toString()输出将会被包含在错误(error)中。

如果<condition>条件返回非真,一条assert语句将抛出一个错误(AssertionError) (注:<condition>表示一个boolean表达式)。默认情况下,Java是忽略Assertions的。你可以通过功能参数 -ea 开启assertions功能。你可以开启(关闭)某些类或包的assertion功能。这就意味着,在开发和测试时,你可以通过assertions功能来验证代码,并且在生产环境中禁用他们,虽然我的测试表明aseertions没有对性能的影响。(这句也翻译残了,~~~~(>_<)~~~~ )

在这种情况下不适用断言也是可以的:代码最终会运行出错。唯一的区别是,断言可能发生的更早些,通过更有意义的方式并且可能伴随着附加的信息,如果你没有预料到这种错误,这可以帮助你找出为什么错误会发生。

第一种情况稍微困难些。如果你在调用的时候,对代码没有控制,那你就完蛋了。如果null是有效的响应,你必须要检查它。

如果你确实对代码做了控制,那么(这是通常的情况),这就是另一回事儿了。避免用null作为响应。几乎不管什么时候,用返回集合的方法,很容易:返回空集(或者空数组)而不是返回nulls。
对于非空集合可能就要难一些。设想这样一个例子:如果你有这些接口

public interface Action {  void doSomething();}public interface Parser {  Action findAction(String userInput);}

其中 Parser (解析器)接受原始用户的输入并找些事做,或许是你正在为某些东西实现一个命令行界面的时候。现在你可能会约定如果没有适当的操作那么就返回null。这就导致了你谈到的为空检查。

另一种解决方法是决不返回null,而是使用Null Object模式:

public class MyParser implements Parser {  private static Action DO_NOTHING = new Action() {    public void doSomething() { /* do nothing */ }  };  public Action findAction(String userInput) {    // ...    if ( /* we can't find any actions */ ) {      return DO_NOTHING;    }  }}
设计1Parser parser = ParserFactory.getParser();if (parser == null) {  // 现在怎么办?  // 这里可能是一个null不是(或不应该是)有效响应的例子}Action action = parser.findAction(someInput);if (action == null) { // do nothing} else {  action.doSomething();}
设计2ParserFactory.getParser().findAction(someInput).doSomething();

对比设计1和设计2,后者是一个更好一些的设计,它使得代码更加简洁。


原本地址:http://stackoverflow.com/questions/271526/avoiding-null-statements-in-java

随记:一是为了英文的进步,一是逼着自己回到技术上来。开始翻译stack overflow上的Highest voted的问题。刚刚开始,翻译错误和理解偏差难免,且翻且学习。




0 0
原创粉丝点击