1

这是我为编码蝙蝠项目写的。出于某种原因,它说这种方式不起作用,但如果我翻转它,它就会起作用。这是为什么?当它输入少于 3 个字符的内容时,它会根据 codebat 收到一条错误消息。

// 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;
4

3 回答 3

6

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

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

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

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

JLS,第 15.23 节谈到了这一点:

条件与运算符 && 类似于 &(第 15.22.2 节),但仅当其左侧操作数的值为真时才计算其右侧操作数。

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

于 2013-10-23T23:11:32.507 回答
3

StringIndexOutOfBoundsException您在上面发布的代码将因if短于三个字符而崩溃str,因为您试图获取一个substring不够长的字符串的 3 个字符。

但是,当您翻转它时,您首先检查字符串的长度。这意味着您立即知道&&将失败(因为str.length >= 3is false),因此您立即从条件中短路。结果,您从不尝试接受不可能的substring事情,并且避免了崩溃。

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

于 2013-10-23T23:11:19.057 回答
0

这是因为你检查

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

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

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

于 2013-10-23T23:12:48.697 回答