Java中的三元表达式是如何评估的?

4

我已经按照提供的教程这里进行了操作,并在以下行中:

boolean t1 = false?false:true?false:true?false:true;

最终的t1的值是false。但我却将其评估为true。 第一个false得到true,而这个true又得到了false,进一步最终得到了true, 我对吗?不,我错了。 你能告诉我Java中如何评估三元表达式吗?

2
你的代码可以简化为boolean t1 = !false && (true ? false : true ? false : true);,其结果始终为false - Ousmane D.
尝试在这个问题上使用括号来使你的生活更轻松。 - Shark
3个回答

5
当编译器发现一个 ? 字符时,它会寻找相应的 :。在 ? 前的表达式是三元条件运算符的第一个操作数,表示条件。
?: 之间的表达式是运算符的第二个操作数,如果条件为真,则返回该值。
: 后面的表达式是运算符的第三个操作数,如果条件为假,则返回该值。
boolean t1 = false   ? false    :    true?false:true?false:true;

             first     second        third
             operand   operand       operand

由于第一个操作数是假的,所以结果是第三个操作数 true?false:true?false:true 的值, 让我们来评估它:

true    ?   false    : true?false:true;

first       second     third
operand     operand    operand

由于第一个操作数为真,所以结果是第二个操作数的值 - false

顺便提一下,第三个操作数 true?false:true 的值也是false,因此无论x的值如何,x?false:true?false:true都将返回false。


4
我们可以根据结合律规则重新分组这些操作。
boolean t1 = (false ? false : (true ? false : (true ? false : true)));
                  |                      |               | 
                  |                      |               1
                  |                      2
                  3

理论上,这应该发生的是:

  1. 先评估Exp 1并作为false进行评估。
  2. 现在Exp 2为:true? false : false,因此最终输出为false
  3. 现在Exp 3变为false ? false : false,即false

现在,让我们来技术性地讲述一下实际发生的:

  1. Exp 3是false ?(不关心):(...) ->需要评估包含Exp 2和Exp 1的内部表达式。
  2. Exp 2是true: false,(不关心)。既然我们已经确定了Exp 2的值,Exp 1就不再需要被评估。
  3. 现在重新评估Exp 3为false ?(不关心):false,因此最终答案为false

实际上,你在“Exp 1”中所表示的代码根本没有被执行。它是无用的代码。 - Eran
@Eran 我试图不让Java初学者感到太过技术化,但我认为提及这点很重要。已更新。 - cs95

1
下面的伪代码展示了如何计算表达式:
boolean t1 = false?false:true?false:true?false:true              
           = true && (true ? false : true ? false : true)
           = true && false
           = false

另一种看待它的方式:
boolean t1 = false?false:true?false:true?false:true;

可以简化为:

可以简化为:

boolean t1 = !false && (true ? false : true ? false : true); 

然后简化为:
boolean t1 = true && (true ? false : true ? false : true); 

然后简化为:
boolean t1 = true && false;

这最终导致false;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接