项目实战:借鉴Android API源码(Splitter-split和TextView-setText),不惧NullPointerException(文末彩蛋)

来源:互联网 发布:csgo和cf对比 知乎 编辑:程序博客网 时间:2024/05/19 10:14

NullPointerException空指针异常可以说是我们开发中最常遇到的Bug,因此我们处处判空,胆战心惊。

处处判空确实可以解决空指针异常的Crash。

但处处判空未免过于草木皆兵,而且写出来的代码十分不优雅,多余判断效率低下,这不是我们的Style!

这里,我们由点到面,借鉴一下Android API中Splitter类的split方法和TextView类的setText方法,我们不惧NullPointerException!

先看一下这几行项目源代码:

        String[] paraString = logPara.split("\\*");        viewHolder.time_tv_networkPara.setText(paraString[0]);        viewHolder.key_tv_networkPara.setText(paraString[1]);        viewHolder.value_tv_networkPara.setText(paraString[2]);

我们不管它的业务意义,简单来说就是通过*分割字符串logPara,然后通过TextView显示出来。

这时,有小伙伴可能会说,如果分割出来为空,然后setText空,那不就空指针异常了吗,吓死宝宝了,赶紧判个空先。

首先,表扬这位小伙伴的风险意识,防患于未然哈,

然而,真的需要在这判空吗?

此时我抽出一个小Demo,我们一步步分析。

正常情况:

private static final String test1 = "2017-02-06 14:25:59:939*/resxxx/xx/xxx/xxxx/xxxOrder/xxxlist*{'xxxId':'0','isXXXX':'0','xxxFlag':0}";public static void main(String[] args) {        String[] paraString = test1.split("\\*");        System.out.println(paraString[0]);        System.out.println(paraString[1]);        System.out.println(paraString[2]);}

输出:

2017-02-06 14:25:59:939
/resxxx/xx/xxx/xxxx/xxxOrder/xxxlist
{'xxxId':'0','isXXXX':'0','xxxFlag':0}

理想结果,ok~


那么我们测一把为空情况呢?

private static final String test2 = "2017-02-06 14:25:59:939**{'xxxId':'0','isXXXX':'0','xxxFlag':0}";

        String[] paraString = test2.split("\\*");        System.out.println(paraString[0]);        System.out.println(paraString[1]);        System.out.println(paraString[1] == null);        System.out.println(paraString[1].equals(""));        System.out.println(paraString[2]);

输出:

2017-02-06 14:25:59:939

false
true
{'xxxId':'0','isXXXX':'0','xxxFlag':0}
此时paraString[1]值为"",但并不为空,因此不存在分割出来为空的情况,最多只是""。不用判空!

在这里我们可以追一下Android API源代码,打破砂锅问到底,知道原理方能决定是否判空,从而游刃有余。

从Sting:

    public String[] split(String regularExpression, int limit) {        String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit);        return result != null ? result : Pattern.compile(regularExpression).split(this, limit);    }

到Pattern:

    public String[] split(CharSequence input, int limit) {        return Splitter.split(this, pattern, input.toString(), limit);    }

再到Splitter:

AndroidSDK/sources/android-23/java/util/regex/Splitter.java

    public static String[] split(Pattern pattern, String re, String input, int limit) {        String[] fastResult = fastSplit(re, input, limit);        if (fastResult != null) {            return fastResult;        }        // Unlike Perl, which considers the result of splitting the empty string to be the empty        // array, Java returns an array containing the empty string.        if (input.isEmpty()) {            return new String[] { "" };        }···

如果为空,则返回一个array,array里有一个空字符串。因此分割出来不会为空,自然不需要判空。

退一步来说,如果遇到其他case,字符串为空,我们setText一个空字符串时是否会有问题呢?

同样,在这里我们追一下Android API源代码,打破砂锅问到底,知道原理方能决定是否判空,从而游刃有余。

AndroidSDK/sources/android-23/android/widget/TextView.java

setText(CharSequence text)

->setText(CharSequence text, BufferType type)

->setText(CharSequence text, BufferType type,boolean notifyBefore, int oldlen)

        if (text == null) {            text = "";        }

至此,真相大白,如果为空,赋值"",不用判空。


小结ing:

1.追溯Android API,打破砂锅问到底,知道原理方能决定是否判空,从而游刃有余,不惧NullPointerException,写出更加优雅的代码。

2.借鉴Android API(Splitter-split和TextView-setText),处理各种case,写出更加健壮的代码。


文末彩蛋:

看到这,小小的过瘾一把,

追加更加优雅,更加健壮的代码是我们不变的信念。


然而,话说回来,有没有觉得什么地方不对劲?

别往下看,先自己沉思三分钟,什么?没啥不对劲?

回过头从头看一遍,什么?挺好的?

哈哈,前面说的是不错,不过有一个问题。

这里确实没有空指针异常,也不需要判空,但是:

添加代码:

System.out.println(paraString[3]);

可能会碰到另一个我们时不时遇见的Bug,

数组越界:java.lang.ArrayIndexOutOfBoundsException

这里就根据自己的业务需求个人处理了~


权兴权意-品质为真

原创不易,转载请注明出处哈。

http://blog.csdn.net/hxqneuq2012/article/details/54892425

0 0
原创粉丝点击