首先需要注意一点,笔者在这里不将"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()方法,这里限于篇幅不在列举。