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