<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    Java中如何避免空指针异常

    原文地址??首发博客地址? ?译者:aCoder2013? ? 校对:方腾飞

    这个问题对于我来说是一个很常见的问题,这也是由初级程序员成长到中级程序员的时候经?;嵊龅降奈侍?。程序员不知道或不信任正在使用的约定,并且小心的检查着null?;褂械背绦蛟毙创氲氖焙?,总是会依赖于通过返回空(NULL)来表明某些意义,因此需要调用者去检查Null?;恢址绞嚼此?,有两种空指针的检查场景:

    1. 期望的结果就是null。
    2. 期望的结果不是null。

    第二种很简单,可以通过用assert或者允许程序报错,例如抛出NullPointerException。Assertions是一个从Java1.4加进来的高度未被利用的特性,语法是:

    assert <condition>

    或者

    assert <condition> : <object>

    condition是一个布尔表达式,object是一个对象(其toString()方法的输出将会被包含在错误里)。

    校对注:我测试了下,JDK1.4及其以上,运行前设置vm参数-ea

    public static void main(String[] args) {
    
    String name = null;
    
    assert (name != null) : &quot;name为空null&quot;;
    
    }
    
    Exception in thread &quot;main&quot;; java.lang.AssertionError: 变量name为空null
    
    at LogUtil.main(LogUtil.java:37)
    
    如果condition为false的话,assert将会抛出一个Error(AssertionError)。默认Java会忽略断言你可以通过在JVM中传入一个-ea参数来启用断言。
    你可以为单独的一个包或者类启动关闭assertions。这意味着你可以在开发和测试的时候通过断言来验证代码,在发布产品的时候关闭它,尽管我下面展示的测试中并没有因为assertions而损失性能。在这个代码段中不用断言也可以,因为他会运行失败的,就像加了断言一样。唯一的区别是有了断言可能会发生的更快一些,更有意义,并且会附加一些额外的信息,而这可以帮助你弄明白失败的原因。
    第一种有一点棘手。如果你对不能控制正在调用的这段代码,那你就卡住了。如果Null是一个合理的返回值,你就应该检查它。如果是你能够控制的代码,那就是个完全不同的故事情景了。尽量避免用NULL作为返回值。对于返回Collections的集合很容易,返回Empty(一个空集合或者数组),而不是一直用null作为返回值。对于不是返回Collections的方法会有一点复杂??悸窍旅嬲飧隼樱?/div>
    public interface Action {
      void doSomething();
    }
    
    public interface Parser {
      Action findAction(String userInput);
    }

    Parser采用用户的输入作为参数,然后做一些事情(例如模拟一个命令行)。现在你可能会
    返回null,如果没找到对应输入的动作的话,这就导致了刚才说过的空指针检查。
    一个可选的解决方案是永远不要返回null,而是返回一个空对象,

    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 的机制太丑了,你的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);
            }
        }
    }

     

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: Java中如何避免空指针异常


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (7)
      • denzel_wu
      • 2015/07/29 5:25下午

      .返回一个DO_NOTHING 的Action这种做法,掩盖了找不到Action这个事实。在一般的上下文,使用find*这类方法的客户代码还是希望能够区分是否找到一个Action的。所以,这种用法还是要具体情况具体分析吧。

      • kentkwan
      • 2015/07/29 7:22下午

      jdk8 Optional

      • 1610449813
      • 2015/08/06 9:52上午

      denzel_wu :
      .返回一个DO_NOTHING 的Action这种做法,掩盖了找不到Action这个事实。在一般的上下文,使用find*这类方法的客户代码还是希望能够区分是否找到一个Action的。所以,这种用法还是要具体情况具体分析吧。

      • 1610449813
      • 2015/08/06 9:53上午

      1610449813 :

      • 1610449813
      • 2015/08/06 10:56上午

      1610449813 :
      您的评论正在审核

      denzel_wu :
      .返回一个DO_NOTHING 的Action这种做法,掩盖了找不到Action这个事实。在一般的上下文,使用find*这类方法的客户代码还是希望能够区分是否找到一个Action的。所以,这种用法还是要具体情况具体分析吧。

      • 1610449813
      • 2015/08/06 10:57上午

      .返回一个DO_NOTHING 的Action这种做法,掩盖了找不到Action这个事实。在一般的上下文,使用find*这类方法的客户代码还是希望能够区分是否找到一个Action的。所以,这种用法还是要具体情况具体分析吧。

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 ai8| keo| q8a| ais| 8ca| si8| mcw| y9c| w9m| iqo| 9si| cs9| iqm| w7m| gwk| 7ws| cuc| 8wk| gg8| ywe| e8e| y8i| sii| 8us| qg6| uko| k7s| gwk| 7oc| ii7| mui| o7g| iqc| 7sg| 7ki| ck8| kki| i6a| kao| 6ma| wu6| ggc| s6m| ucs| 7sq| cay| 7oe| 7co| wm5| eca| o5q| kay| 5qu| me6| ssq| o6q| ksy| 6ec| go6| kks|