判斷String是否為空的注意事項
首先需要注意一點,筆者在這裡不將"s==nul"l的情況視為"s是空字串"。
一,初學者容易出現的錯誤
1、用if(s==""){}判斷s是否為空。
這種方式是最低階的錯誤同時也是最隱蔽的錯誤,說它低階是因為這樣構造語句的程式設計師對String瞭解甚少,說它隱蔽是因為這條語句不僅不會發生編譯錯誤而且很多新手還會認為這樣判斷完全正確,殊不知存在嚴重的bug。先看下面的示例:
示例一:
public class TestEmpty{
public static void main(String args[]){
String s="";
//String s=new String("");
if(s==""){
System.out.println("empty");
}
}
}
解析:將該程式執行兩次,第一次s用String s=""定義,第二次s用String s=new String("")定義,你會發現第一次執行時會輸出empty,而第二次執行時沒有輸出empty,這就是程式的bug所在。如果你對String比較瞭解的話,一定知道其中的原因;為了方便閱讀我在這裡再簡單的解釋一下原因:第一次的定義方式中,s指向的是String池中的"",if語句中的s同時也是和String池中的""比較,故s==""返回true;第二次的定義方式中,s指向的是堆中的"",但是if語句中的s此時仍然是和Sting池中的""比較,故s==""返回false。
2、直接用if(s.equals("")){}或if(s.length()<=0){}或if(s.isEmpty()){}來判斷
這種方式從原理上來說是正確的,但是考慮不是很周全、程式存在bug,這也是程式設計師經常犯的一個錯誤,請看下面的示例:
示例二:
public class TestEmpty{
public static void main(String args[]){
String s=null;
if(s.equals("")){
System.out.println("empty");
}
/*if(s.length()<=0){
System.out.println("empty");
}
if(s.isEmpty()){
System.out.println("empty");
}*/
}
}
解析:執行該程式三次,每次只讓三個if語句中的一個有效,你會發現三次都會丟擲NUllPointerException異常,這是因為程式中s==null,它指向不確定的物件,無法呼叫一個確定的Sting物件的方法。所以我們的判斷語句應該先對s進行是否為null的判斷,故應該是if(s!=null&&s.equals(""))的形式,其他兩個同理。
二、效率問題
上面示例二中有三種方法來判斷s是否為空,那麼究竟哪種方式速度更快、效率更高呢?請看下面的示例(該示例引用某仁兄的程式碼):
示例三:
public class TestEmpty{
String s = "";
long n = 10000000;
private void function1(){
long startTime=System.currentTimeMillis();
for(long i=0;i<n;i++){
if(s!=null&&s.equals(""));
}
long endTime=System.currentTimeMillis();
System.out.println("function 1 use time: "+(endTime-startTime)+"ms");
}
private void function2(){
long startTime=System.currentTimeMillis();
for(long i=0;i<n;i++){
if(s!=null&& s.length()<=0);
}
long endTime = System.currentTimeMillis();
System.out.println("function 2 use time:"+(endTime-startTime)+"ms");
}
private void function3(){
long startTime=System.currentTimeMillis();
for(long i=0;i<n;i++){
if(s!=null&&s.isEmpty());
}
long endTime = System.currentTimeMillis();
System.out.println("function 3 use time:"+ (endTime-startTime)+"ms");
}
public static void main(String[] args) {
TestEmpty te=new TestEmpty();
te.function1();
te.function2();
te.function3();
}
}
解析:多執行程式幾次,你會發現function2()和function3()的執行時間基本相同,但是function1()的執行時間基本上是"f2"和"f3"的兩倍,由此可見equals()方法的效率是最低的,其他兩個方法效率基本相同。equals()效率的原因是其方法內部有迴圈語句,讀者可以看一下Sting類的java原始碼,比較一下equals()、length()和isEmpty()方法,這裡限於篇幅不在列舉。