Java中避免!= null语句

问题:

在Java中编程时使用最多的成语是在使用它之前测试object != null。这是为了避免NullPointerException。我发现这个代码非常丑陋,它变得无法读取。
有没有一个很好的选择呢?
如果要访问此对象的字段或方法,我想要解决测试每个对象的必要性。
例如:

if (someobject != null) {
    someobject.doCalc();
}

在这种情况下,我将避免NullPointerException,我不知道对象是否为null。因此,在我的代码中出现这些测试。

回答:

对我来说这听起来像是一个相当普遍的问题,初级到中级开发人员往往面临一些时刻:他们不知道或不信任他们参与的合同,并且防守地超过了空值。另外,当编写自己的代码时,他们倾向于依赖返回null来指示一些事情,从而要求调用者检查null。
换句话说,有两种情况是空检:

  1. 如果合同中的null是有效的答复;和
  2. 哪里不是有效的回应。

(2)很容易。使用assert语句(断言)或允许失败(例如NullPointerException)。断言是在1.4中添加的高度欠缺的Java功能。语法是:

assert <condition>

要么

assert <condition> : <object>

其中<condition>是一个布尔表达式,<object>是一个对象,其toString()方法的输出将包含在错误中。
如果条件不为真,assert语句将抛出ErrorAssertionError)。默认情况下,Java忽略断言。您可以通过将选项-ea传递到JVM来启用断言。您可以启用和禁用单个类和包的断言。这意味着您可以在开发和测试过程中使用断言来验证代码,并在生产环境中禁用代码,尽管我的测试显示在断言之后没有对性能的影响。
在这种情况下不使用断言是OK的,因为代码将失败,如果使用断言,会发生什么。唯一的区别是,通过断言,它可能会以更有意义的方式发生,并且可能会提供额外的信息,这可能有助于您了解为什么如果您不期待它会发生什么。
(1)有点难如果您无法控制您正在呼叫的代码,那么您将被卡住。如果null是有效的响应,则必须检查它。
然而,如果它是您所控制的代码(通常是这种情况),则这是一个不同的故事。避免使用null作为响应。使用返回集合的方法,这很简单:几乎都是返回空集合(或数组)而不是null。
使用非集合可能会更难。以此为例:如果您有以下接口:

public interface Action {
  void doSomething();
}

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

Parser采用原始用户输入并找到可以做的事情,也许如果您正在为某些实现命令行界面。现在,如果没有适当的操作,您可以使合同返回null。这导致你正在谈论的空检。
一个替代方案是永远不返回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();
}

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

这是一个更好的设计,因为它导致更简洁的代码。
也就是说,findAction()方法可能会抛出一个有意义的错误消息,特别是在这种情况下,您依赖于用户输入是完全合适的。对于findAction方法来说,抛出异常比调用方法要好一点,就是用一个简单的NullPointerException来解释。

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

或者如果您认为try / catch机制太丑陋,而不是Do Nothing,您的默认操作应该向用户提供反馈。

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

Code问答: http://codewenda.com/topics/python/
Stackoverflow: Avoiding != null statements

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

67 − = 63