if语句的细微变化导致意外结果

时间:2013-10-29 23:56:58

标签: java if-statement

为什么这样做:

public String delDel(String str) {
if(str.length() >= 4 && str.substring(1,4).equals("del")){    
        String front = str.substring(0,1);
        String back = str.substring(4, str.length());
        return front + back;
    }
    else{
        return str;
    }
}

这不起作用:

public String delDel(String str) {
if((str.substring(1,4).equals("del")) && str.length() >= 4){    
        String front = str.substring(0,1);
        String back = str.substring(4, str.length());
        return front + back;
    }
    else{
        return str;
    }
}

如果你注意到第一个和第二个之间的区别是str.length()在第一个条件的其余条件之前,它是第二个条件中的最后一个条件。

2 个答案:

答案 0 :(得分:4)

差异表明了短路评估。

在Java中,使用布尔运算符&&,如果第一个操作数为false,则不会计算第二个操作数。当能够评估的第二个操作数取决于第一个条件为true时,这种差异是至关重要的。

第一个代码示例:

if(str.length() >= 4 && str.substring(1,4).equals("del")){    

如果长度为4,则仅评估第二部分。如果长度不是至少4,则substring将失败并且StringIndexOutOfBoundsException。但它不能,因为如果长度至少为4,则呼叫有效。

第二个代码示例:

if((str.substring(1,4).equals("del")) && str.length() >= 4){    

现在,无论长度如何,都将始终评估对substring的调用,因此可以抛出StringIndexOutOfBoundsException

即使是JLS, Section 15.23,也有关于这个主题的说法:

  

条件和操作员&&就像& (§15.22.2),但仅在其左侧操作数的值为真时才计算其右侧操作数。

此外,根据JLS, Section 15.24,条件或运算符||的工作方式类似:

  

条件或运算符||运算符就像| (§15.22.2),但仅在其左侧操作数的值为假时才计算其右侧操作数。

答案 1 :(得分:1)

第二个条件可能不起作用的原因是当str短于4个字符时,您将在第二个条件中看到失败。但是,第一个条件可以防止这种情况发生,因为&&运算符在长度小于substr时不会评估4