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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值