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