【问题标题】:Java Logical Operator And/Or PrecedenceJava 逻辑运算符和/或优先级
【发布时间】:2019-08-03 16:57:45
【问题描述】:

所以无论我在哪里看,它都说首先评估 &&,然后 ||被评估为第二。所以要么我做错了什么,要么是错的。代码如下:

static boolean foo(boolean b, int id){ System.out.println(id); return b;}

static{ System.out.println(foo(true, 3) && foo(true, 1) || foo(false, 2)) }
//returns 3 1

static{ System.out.println(foo(true, 2) || foo(true, 3) && foo(true, 1)} 
//returns 2

在第一个静态块中, && 先行,短路并忽略 ||但在第二个静态块中,这只是相反,||首先忽略 &&。这演示了从左到右,但根据 java 文档,&& 具有更高的优先级,这意味着 && 应该始终排在第一位。

一些关于优先级的文档(逻辑and高于or):
1.https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
2.https://chortle.ccsu.edu/Java5/Notes/chap40/ch40_16.html
3.http://www.cs.bilkent.edu.tr/~guvenir/courses/CS101/op_precedence.html
...

【问题讨论】:

  • 从左到右评估...不确定您在看哪里。
  • 我认为发生的事情是逻辑被短路了。在评估|| 时,一旦获得true,则不需要评估表达式的其余部分,因为它已经是true,这是正常的。如果您有不同的想法,请告诉我们。
  • 不,我不认为这是正确的。即使 && 更高,只要 || 的左侧仍然是正确的为真,则整个表达式为真。在某些方面,我认为你有它倒退。因为 && 具有更高的优先级,这意味着 ||走在最后,然后控制最终结果。用真值表算出来,看看我是否正确。
  • P. S. 请记住,短路评估要求首先评估左侧,所以这就是 ||和 && 正在做。这就是为什么第一个输出有两个输出,第二个输出只有一个。
  • 这里太混乱了。 1. 操作数从左到右计算。 2. 算子按优先级计算。 3.如果LHS为假,则不评估&&的RHS。 4. 如果 LHS 为真,则不评估 || 的 RHS。

标签: java logic operators


【解决方案1】:

&& 的优先级更高只是意味着

foo(true, 2) || foo(true, 3) && foo(true, 1)

相同
foo(true, 2) || (foo(true, 3) && foo(true, 1))

但不是

(foo(true, 2) || foo(true, 3)) && foo(true, 1)

没有别的了。它并不意味着任何关于评估顺序的事情。

现在,对于大多数运营商而言,评估 x op y 需要同时评估 xy。如果|| 是其中之一,则与(return 来自评估||,而不是来自整个方法)

boolean tmp1 = foo(true, 2);
boolean tmp2 = foo(true, 3) && foo(true, 1);
return tmp1 || tmp2;

&& 确实会“先行”。但是有三个运算符不能这样工作:&&||?:。相反,您会得到

boolean tmp1 = foo(true, 2);
if (tmp1) {
    return true; 
} else {
    return foo(true, 3) && foo(true, 1);
}

【讨论】:

  • 我理解短路的意义。如果它可以保证完整的评估为真,则不评估右侧。但是 foo(true, 2) || (foo(true, 3) && foo(true, 1)) -> && first 因为它有更多的括号对吗?例如:a + (b + (c + d)) 其中 (a, b, c, d) = (1, 2, 3, 4) -> 1 + (2 + (3 + 4)) -> 1 + (2 + 7) -> 1 + 9 -> 10
  • 你能给我一个例子吗||然后 && 从左到右先 && ?
  • "但是 foo(true, 2) || (foo(true, 3) && foo(true, 1)) -> && first 因为它有更多的括号对吗?例如:a + ( b + (c + d))" 没有。首先是左侧foo(true, 2),然后是foo(true, 3) && foo(true, 1)如果需要(它不是)。如果||&& 没有短路,则顺序为: 1. foo(true, 2); 2.foo(true, 3); 3.foo(true, 1); 4.&&; 5.||。但他们确实如此。
  • "你能给我举个例子,|| 然后 && 从左到右先 && 吗?"只需将trues 更改为false。但即便如此: 1. foo(false, 2)&& 之前首先被执行。 2. 你可以说&&|| 内部被评估,而不是在它之前。但它在|| 之前完成。
  • 我真的不知道如何更简单地解释它。您正在检查的是它首先评估 || 的左侧。但同样的情况也会发生在任何运算符身上,无论它们的优先级是什么(以及它们是否短路)。但是&& || 之前完成(在本例中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 1970-01-01
相关资源
最近更新 更多