Java 为什么这个布尔表达式不工作?

Java 为什么这个布尔表达式不工作?,java,Java,这是我为一个编码bat项目写的东西。出于某种原因,它说这种方式不起作用,但如果我翻转它,它就起作用了。为什么呢?当它输入少于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 unch

这是我为一个编码bat项目写的东西。出于某种原因,它说这种方式不起作用,但如果我翻转它,它就起作用了。为什么呢?当它输入少于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;

如果
str
短于三个字符,则您上面发布的代码将因
StringIndexOutOfBoundsException
崩溃,因为您试图获取一个不够长的字符串的三个字符的
子字符串

但是,当您翻转它时,首先检查字符串的长度。这意味着您马上就知道
&&
将失败(因为
str.length>=3
false
),因此您可以立即退出条件。因此,您从不尝试使用不可能的
子字符串
,从而避免了崩溃


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

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

但是,当您翻转它时,首先检查字符串的长度。这意味着您马上就知道
&&
将失败(因为
str.length>=3
false
),因此您可以立即退出条件。因此,您从不尝试使用不可能的
子字符串
,从而避免了崩溃


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

如果字符串的长度不至少为3,则
str.substring(0,3)
将因
IndexOutOfBoundsException
而失败

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

if ( str.length() >= 3 && str.substring (0,3).equalsIgnoreCase("not") )
评估第一个条件。如果小于3,那么Java知道整个条件是
false
,因为
false&&anything
false
。它不会计算另一个表达式,因为它不必计算它。
IndexOutOfBoundsException
不是出于这个原因而出现的

关于此,

条件and运算符&&与&(§15.22.2)类似,但计算 仅当其左侧操作数的值为 对


此外,逻辑or运算符(条件or运算符)
|
的工作原理类似。仅当左侧操作数为
false
()时,它才会计算其右侧操作数。

如果字符串的长度不至少为3,则
str.substring(0,3)
将因
索引自动边界异常而失败

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

if ( str.length() >= 3 && str.substring (0,3).equalsIgnoreCase("not") )
评估第一个条件。如果小于3,那么Java知道整个条件是
false
,因为
false&&anything
false
。它不会计算另一个表达式,因为它不必计算它。
IndexOutOfBoundsException
不是出于这个原因而出现的

关于此,

条件and运算符&&与&(§15.22.2)类似,但计算 仅当其左侧操作数的值为 对

此外,逻辑or运算符(条件or运算符)
|
的工作原理类似。仅当左侧操作数为
false
()时,它才会计算其右侧操作数。

这是因为您检查了

str.substring (0,3).equalsIgnoreCase("not") 
首先,在检查长度之前。因此,如果str的长度小于3,则可能会生成错误
java.lang.StringIndexOutOfBoundsException

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

这是因为你检查了

str.substring (0,3).equalsIgnoreCase("not") 
首先,在检查长度之前。因此,如果str的长度小于3,则可能会生成错误
java.lang.StringIndexOutOfBoundsException


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

因为您首先获取
子字符串
,然后检查其
长度
。如果
长度
小于3,会发生什么情况。
&&
的第一部分将导致错误。我猜这是编译器处理这个场景的方式。您可以使用
str.startsWith(“not”)
而不是使用
str.substring(0,3).equalsIgnoreCase(“not”)
来代替,如果我们想忽略这个案例,您可以添加
str.toLowerCase().startsWith(“not”)
因为您首先获取
子字符串
,然后检查其
长度
。如果
长度
小于3,会发生什么情况。
&&
的第一部分将导致错误。我猜这是编译器处理这个场景的方式。你可以使用
str.startsWith(“not”)
而不是使用
str.substring(0,3).equalsIgnoreCase(“not”)
你可以使用
str.startsWith(“not”)
如果我们想忽略这个案例,你可以添加
str.toLowerCase().startsWith(“not”)
哇,好了,现在我明白了。感谢所有对此问题做出贡献的人!哇,好吧,现在我明白了。感谢所有对此问题做出贡献的人