如何避免非空判断

    刚开始编程时,我们经常面对这样的情况,我们不知道也不相信我们的方法协议,所以过多的进行非空检查。而且,我们经常返回null,导致调用者要进行非空检查。

    有两种情况会出现非空检查:

    1. null是个合法的返回值,对于我们定义的方法协议而言;

    2. null不知一个合法的返回值。

    情况(2)很简单。我们可以使用assert语句,或者允许方法失败(比如,空指针异常)。断言是一个经常使用的Java特性,在1.4版本添加的。它的语法如下:

asset <condition>

    或者

assert <condition> : <object>

    <condition>是一个布尔表达式,<object>的toString()方法的返回值就是错误信息。

    如果<conditoin>不成立,assert语句会抛出一个Error(AssetionError)。默认情况下,Java会忽略这些断言。你可以通过传递-ea参数给JVM来启用断言。你甚至可以为单独的package或者class启用和禁用断言。也就是说,你可以在开发和测试环境下启用断言,而在生产环境下禁用断言。

    这种情况下,不用断言也可以,因为程序一样会失败。唯一的区别是,使用断言会让程序更早的、在更合理的场合失败,同时会提示有意义的信息。

    情况(1)有点复杂。如果你不能控制你所调用方法的返回值,那就有点麻烦了。如果null是一个合法的返回值,你就必须去检查它。

    如果你能控制你调用的方法,情况就不一样了。避免使用null作为返回值。如果方法的返回值是一个Collection,返回EmptyCollection而不返回null是一个明智的选择。

    如果返回值不是集合,就又有点难办了。考虑下面的情况,如果你有这样的接口:   

public interface Action {
  void doSomething();
}

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

   Parser接受用户的输入并进行解析,比如实现一个命令行的接口。现在你会允许这个方法返回null,如果没有合法的Action。这就会导致我们说的非空检查。

    一个选择是不返回null,而是使用Null Object Pattern

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

   

    对比

Parser parser = ParserFactory.getParser();if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response}Action action = parser.findAction(someInput);if (action == null) {
  // do nothing} else {
  action.doSomething();}

    和

arserFactory.getParser().findAction(someInput).doSomething();

    后者是一个更好的写法,因为代码更简洁。

    也就是说,由findAction()方法抛出一个异常,这个异常含有有意义的信息,这种方式更恰当。它比调用函数抛出一个NullPoninterExceptiong更友好。

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

    如果你觉得try/catch语句不够简洁,可以构造一个给用户反馈的Action。

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}

转载于:https://my.oschina.net/kisscoder/blog/667282

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值