java 中相等和条件运算符的优先级

Priority of equality and conditional operators in java

我运行下面的代码片段

System.out.println(T1() ? F1() : T2() == T3() ? F2() : T4());
public static boolean T1() { System.out.println("true1"); return true; }
public static boolean T2() { System.out.println("true2"); return true; }
public static boolean T3() { System.out.println("true3"); return true; }
public static boolean T4() { System.out.println("true4"); return true; }
public static boolean F1() { System.out.println("false1"); return false; }
public static boolean F2() { System.out.println("false2"); return false; }

我得到了输出

true1
false1
false

第一个三元运算符在之前计算等于运算符,但根据oracle documentation,等于运算符比三元运算符具有更高的优先级,因此等于运算符必须在三元之前进行评估。

出现这种代码行为的原因是什么?

JLS 15.25

The conditional operator is syntactically right-associative (it groups right-to-left). Thus, a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).

在你的情况下:

T1() ? F1() : (T2() == T3() ? F2() : T4())
  a     b            c         d       e

T1() 被计算为真,返回真,所以接下来只有 F1() 被计算。

T2() == T3() 永远不会计算。您的代码等于:

if(T1()) {
  System.out.println(F1());
}
else {
  if(T2() == T3()) {
    System.out.println(F2());
  }
  else {
    System.out.println(T4());
  }
}

在这里你清楚地看到为什么它从未被评估 - 因为 T1() 为真并且从未输入 else 块。

您似乎误解了优先级的含义。 == 比三元运算符具有更高优先级的事实并不意味着在表达式中所有 == 子表达式都首先被评估。在某些情况下,优先级只是一种省略括号的方法。

例如表达式

a == b ? c : d

可能等同于 (a==b) ? c : da == (b ? c : d)。 == 具有更高优先级的事实意味着它实际上等同于第一个。

表达式中

a ? b : c == d

没有歧义,总是等价于a ? b : (c == d)。由于三元运算符是延迟计算的,如果 a 成立,则永远不会计算 c == d