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


原问题:

我整天都在用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;
    }
  }
}

设计1
Parser parser = ParserFactory.getParser();
if (parser == null) {
  // 现在怎么办?
  // 这里可能是一个null不是(或不应该是)有效响应的例子
}
Action action = parser.findAction(someInput);
if (action == null) {
 // do nothing
} else {
  action.doSomething();
}
设计2
ParserFactory.getParser().findAction(someInput).doSomething();

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



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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值