为什么这个布尔表达式无法翻转?

时间:2013-10-23 23:07:39

标签: java

这是我为编码蝙蝠项目写的东西。由于某种原因,它说这种方式不起作用,但如果我翻转它,它的工作原理。这是为什么?当它输入少于3个字符的内容时,它会根据codingbat获得错误消息。

// Given a string, return a new string where "not " has been added to the front. 
// However, if the string already begins with "not", return the string unchanged. 
// Note: use .equals() to compare 2 strings. 

// notString("candy") → "not candy"
// notString("x") → "not x"
// notString("not bad") → "not bad"

        public String notString(String str) {
                  String m;
          if ( str.substring (0,3).equalsIgnoreCase("not") && str.length () >= 3 ) // this line doesn't work in it's current state 
          // but works if I flip the two boolean expressions over the &&

                    m = str;
          else {
                    m = "not " + str;
                }
       return m;

3 个答案:

答案 0 :(得分:6)

如果字符串的长度不是至少为3,那么str.subtring(0, 3)将失败并显示IndexOutOfBoundsException

翻转时工作的原因称为短路评估。翻转:

if ( str.length() >= 3 && str.substring (0,3).equalsIgnoreCase("not") )

评估第一个条件。如果它小于3,那么Java知道整个条件是false,因为false && anythingfalse。它不会评估另一个表达式,因为它不必评估它。 IndexOutOfBoundsException不是出于这个原因。

JLS, Section 15.23谈到这个问题:

  

条件和操作员&&就像& (§15.22.2),但评估   只有当左侧操作数的值为时,它的右侧操作数   真。

此外,逻辑或运算符(条件运算符或运算符)||的工作方式类似。如果左侧操作数为falseJLS Section 15.24),它将仅评估其右侧操作数。

答案 1 :(得分:3)

如果StringIndexOutOfBoundsException短于三个字符,则您在上面发布的代码会因str而崩溃,因为您尝试使用不是3个字符substring的字符串够久了。

但是,当你翻转它时,你会检查字符串的长度。这意味着您立即知道&&将失败(因为str.length >= 3false),所以您short-circuit出于条件权利之后就在那里。因此,您永远不会尝试采用不可能的substring,并避免崩溃。

如链接中所述,逻辑运算符的两个以这种方式工作(&&(AND)和||(OR))。如果他们能够在仅评估左侧之后找出要返回的内容,则右侧不会被触及。因此,例如,(true || 1/0 == 0)将始终评估为true,即使要评估右侧,也会引发异常。

答案 2 :(得分:0)

这是因为你检查了

str.substring (0,3).equalsIgnoreCase("not") 

首先,在检查长度之前。因此,如果您的str长度小于3,则可以生成错误java.lang.StringIndexOutOfBoundsException

您必须先检查长度(例如通过翻转条件检查)。