Java:短篇小说&&在OR之后

时间:2017-12-19 15:05:34

标签: java if-statement short-circuiting

我理解&&||在Java中被短路(而&|则没有)

但是,我不明白为什么以下代码(以短路OR开头但以&&&条件结束)也被短路:

String x, y;
if ( x.contains("this") || x.contains("that") && y.contains("something else")!= true)

我认为即使条件x.contains("this")评估为真,程序仍然需要评估最后一个条件y.contains("something else") != true,因为有&&&操作员在最后一个条件之前但显然事实并非如此。

任何人都可以解释原因吗?

7 个答案:

答案 0 :(得分:4)

这里有两个因素可以确定评估顺序:

  • 操作优先级,
  • 短路规则

由于&&高于<{em> 优先级高于||,因此运算符&&“更接近其操作数”,因此您的表达式解析如下:

Parse tree

因为&&||运算符都是从左到右关联的 * ,所以Java会从左到右评估此表达式,一旦确定该表达式就会停止结果。如果字符串包含"this"子字符串,则评估将在不评估&&的情况下停止。

注意:如果您不确定操作的顺序,可以通过括号部分谓词来强制执行所需的顺序。如果表达对你来说并不完全明显,很有可能它对其他读者来说是不明显的,所以添加一些额外的括号是个好主意。

* 某些运算符是从右到左的关联。例如,赋值运算符a[i] = b + c在评估b + c之前评估a[i]。感谢T.J. Crowder发表了精彩的评论。

答案 1 :(得分:3)

这是因为运营商优先。

你的(a || b&amp;&amp; c)的等价形式是(a ||(b&amp;&amp; c))

比照。 https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

答案 2 :(得分:2)

  

...即使条件x.contains("this")评估为真,程序仍需要评估最后一个条件y.contains("something else") != true ......

不。 :-)该表达式中||的操作数是

  • x.contains("this")

  • x.contains("that") && y.contains("something else")!= true

...因为&&的优先级高于||details)。因此,如果您有a || b && c,那就是a || (b && c)(就像a + b * c a + (b * c)而不是(a + b) * c)。优先级定义操作数的分组方式。

如果您希望对表达式进行不同的分组,可以使用()对其进行分组。

if ( (x.contains("this") || x.contains("that")) && y.contains("something else")!= true)

答案 3 :(得分:1)

这是java中语法的工作方式&amp;&amp;操作在||之前分组操作,因此当它读取等式(A || B&amp;&amp; C)时,它只看到比较A || D(其中D实际上是B&amp; C)。因此,当A被评估为True时,它甚至不需要评估B&amp;&amp; C。 有关操作顺序的更多语法相关问题,请参阅此链接 https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

答案 4 :(得分:1)

它与operator precedence有关。大多数标准运算符都是二进制运算符,即它们采用两个输入并生成输出。每当你有一个包含两个以上运算符的表达式时,编译器就会使用优先级和关联性规则来弄清楚如何将该表达式转换为清楚每个操作具有哪些输入的表达式。

在您的情况下,您有一个类似A || B && C的表达式。 &&的优先级高于||,因此编译器会将其解释为A || (B && C),而不是像(A || B) && C一样,只需查看表达式就可以得到它。

这意味着A对于整个表达式为真是足够的。

答案 5 :(得分:0)

GridView1.DataSource = Liste_template; GridView1.DataBind(); 是一个优先级高于&&的运算符 优先级较高的运算符在优先级较低的运算符之前进行求值。

所以这里:

||

这两个表达式一起评估:

if ( x.contains("this") || x.contains("that") && y.contains("something else")!= true)

所以你得到一个带有以下形式的条件语句:  x.contains("that") && y.contains("something else")!= true

if (something || somethingElse)something,因此永远不会评估true 整个条件语句是somethingElse

答案 6 :(得分:0)

Java有一些operator precedence。您需要了解它才能使用它。

<小时/> 首先

在if语句中,您有两个逻辑运算符:||&&
您知道短路。但您需要知道&&运算符将首先运行|| AND运营商(&amp;&amp;)

首先,&&运算符将验证左侧条件。没有必要检查其中两个,&&返回true,如果第一个为真,那么他可以检查第二个。 OR运算符(||)

||运算符将在&&之后立即执行。它将验证这两个条件是否返回false,因此他需要验证两者。 的括号

您应该知道,但要使其按您希望的方式工作,您需要使用括号()。要以您需要的方式执行此操作,请使用()向if语句提供新规则:

if ( (x.contains("this") || x.contains("that")) && y.contains("something else")!= true)