String的null或空值的判斷處理
筆者在開發(fā)過程中,常常碰到過下面這些錯(cuò)誤的用法:
1,錯(cuò)誤用法一:
1
2
3
|
if (name == "" ) { //do something } |
2,錯(cuò)誤用法二:
1
2
3
|
if (name.equals( "" )) { //do something } |
3,錯(cuò)誤用法三:
1
2
3
|
if (!name.equals( "" )) { //do something } |
我們來解說一下:
上述錯(cuò)誤用法1是初學(xué)者最容易犯,也最不容易被發(fā)現(xiàn)的錯(cuò)誤,因?yàn)樗鼈兊恼Z法本身沒問題,Java編譯器編譯時(shí)不報(bào)錯(cuò)。但這種條件可能在運(yùn)行時(shí)導(dǎo)致程序出現(xiàn)bug,永遠(yuǎn)也不會(huì)為true,也就是時(shí)說,if塊里的語句永遠(yuǎn)也不會(huì)被執(zhí)行。
上述用法二,用法三 的寫法,是包括很多Java熟手也很容易犯的錯(cuò)誤,為什么是錯(cuò)誤的呢?也許你會(huì)感到納悶。
對(duì),它們的寫法本身沒錯(cuò),但是,少了一個(gè)null判斷的條件,試想,如果name=null的情況下,會(huì)發(fā)生什么后果呢?后果是,你的程序?qū)伋鯪ullPointerException異常,系統(tǒng)將被掛起,不再提供正常服務(wù)。
當(dāng)然,如果之前已經(jīng)對(duì)name作了null判斷的情況例外。
正確的寫法應(yīng)該先加上name != null的條件,如例:
1
2
3
|
if (name != null && !name.equals( "" )) { //do something } |
或者
1
2
3
|
if (! "" .equals(name)) { //將""寫在前頭,這樣,不管name是否為null,都不會(huì)出錯(cuò)。 //do something } |
下面,我們舉一個(gè)簡(jiǎn)單的例子:
TestNullOrEmpty.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class Test { public static void main (String args[]){ String value = null ; testNullOrEmpty(value); value = "" ; testNullOrEmpty(value); value = " " ; testNullOrEmpty(value); value = "hello me" ; testNullOrEmpty(value); } static void testNullOrEmpty(String value){ if (value == null ){ System.out.println( "value is null" ); } else if ( "" .equals(value)){ System.out.println( "value is blank but not null" ); } else { System.out.println( "value is \"" + value + "\"" ); } if (value == "" ) { //NG 錯(cuò)誤的寫法 //別用這種寫法 } } } |
編譯執(zhí)行:
1
2
3
|
c:\>javac TestNullOrEmpty.java c:\>java TestNullOrEmpty |
1
2
3
4
|
value is null. value is blank but not null. value is " " value is "hello me!" |
比較String地址相等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package com; public class A { /** * @param args */ public static void main(String[] args) { String a = "hello" ; String b = "he" ; String c = a.substring( 0 , 2 ); System.out.println(b.equals(c)); //true System.out.println(b==c); //false String d = new String( "hello" ); System.out.println(d.equals(a)); //true System.out.println(d==a); //false String e = new StringBuilder( "hello" ).toString(); System.out.println(e.equals(a)); //true System.out.println(e==a); //false System.out.println(e.equals(d)); //true System.out.println(e==d); //false String f = "hello" ; System.out.println(f.equals(a)); //true System.out.println(f==a); //true System.out.println(f== "hello" ); //true System.out.println(f== "hell" + "o" ); //true String g = b+ "llo" ; System.out.println(g==f); //false String h = "he" + "llo" ; System.out.println(h==f); //true } } |
總結(jié):
1.new出來的String是重新分配內(nèi)存,字符串不共享,new出來的多個(gè)之間也不共享。
2.通過字符串函數(shù)操作拼接或者截取到的字符串跟靜態(tài)字符串變量也是不共享的。
3.通過加號(hào)得到的字符串有兩種情況。
A "he"+"llo"是靜態(tài)字符串,是共享的
B String a = "He"; a+"llo"不是靜態(tài)字符串,是不共享的