当前位置: 首页 > 面试题库 >

为什么x ==(x = y)与(x = y)== x不同?

乐正辰阳
2023-03-14
问题内容

考虑以下示例:

class Quirky {
    public static void main(String[] args) {
        int x = 1;
        int y = 3;

        System.out.println(x == (x = y)); // false
        x = 1; // reset
        System.out.println((x = y) == x); // true
     }
}

我不确定Java语言规范中是否有一项规定要加载变量的先前值以便与右侧(x = y)进行比较,该变量应按照方括号内的顺序进行计算。

为什么第一个表达式求值false,而第二个表达式求值true?我本来希望(x = y)先被评估,然后再x与自身(3)比较并返回true

这个问题与Java表达式中子表达式的求值顺序不同,因为x这里绝对不是“子表达式”。需要
加载 它以进行比较,而不是对其进行“评估”。这个问题是特定于Java的x == (x = y),与通常为棘手的面试问题设计的牵强的不切实际的构造不同,该表达式来自一个真实的项目。它本来是用于替换和替换成语的单行替换

int oldX = x;
x = y;
return oldX == y;

它比x86 CMPXCHG指令还要简单,因此值得在Java中使用较短的表达式。


问题答案:

首先应按照括号中的顺序计算

不会。圆括号对计算或评估顺序有任何(一般)影响,这是一个普遍的误解。它们仅将表达式的各部分强制转换为特定的树,将正确的操作数绑定到作业的正确操作。

(而且,如果您不使用它们,则此信息来自运算符的“优先级”和关联性,这是语言的语法树定义方式的结果。实际上,这仍然是您使用语言时的工作方式使用括号,但我们简化并说我们当时不依赖任何优先规则。)

一旦完成(即,将您的代码解析为程序),仍然需要对那些操作数进行求值,并且有分别的操作规则:所述规则(如安德鲁向我们展示的那样)指出每个操作的LHS首先用Java评估。

请注意,并非所有语言都如此。例如,在C
++中,除非您使用短路运算符(如&&或)||,否则操作数的求值顺序通常是不确定的,并且您不应以任何方式依赖它。

教师需要停止使用具有误导性的短语来解释操作员优先级,例如“这使得添加首先发生”。给定一个表达式x * y + z,正确的解释是“运算符优先级使在x * y和之间进行加法z,而不是在y和之间进行加法,而z没有提及任何”顺序”。



 类似资料:
  • 这个问题与Java表达式中子表达式的求值顺序不同,因为在这里肯定不是“子表达式”。需要加载它进行比较,而不是“求值”。这个问题是特定于Java的,表达式来自一个真实的项目,而不是通常为棘手的面试问题而设计的牵强附会的不切实际的构造。它应该是比较和替换习语的一行替换 它比x86 CMPXCHG指令还要简单,因此在Java中应该使用更短的表达式。

  • 我有以下功能: 此代码给出了

  • 问题内容: 使用math.pow或**运算符哪个更有效?我什么时候应该使用另一个? 到目前为止,我知道可以返回一个或一个,如果您使用小数,该函数将返回一个浮点数 问题答案: 使用Power运算符将更快,因为它不会产生函数调用的开销。如果您反汇编Python代码,则可以看到以下内容: 请注意,我在这里使用变量作为指数,因为类似常数的表达式实际上是在编译时求值的。 现在,实际上,这种差异并不重要,正如

  • X|Y

    描述 (Description) 逻辑运算符[X|Y]匹配X或Y. 例子 (Example) 以下示例显示了逻辑运算符的用法。 package com.wenjiangs; import java.util.regex.Matcher; import java.util.regex.Pattern; public class LogicalOperatorDemo { private sta

  • 将返回来自x(包括)和y(不包括)的流。将返回来自x(含)和y(含)的流。 我期望调用或调用。但是当查看的源代码时,它是这样的: 也有一个非常相似的实现,而不是。唯一的区别是的第三个参数是而不是表示范围已关闭。 然后使用此布尔值初始化类中的字段,并针对它提到以下注释: 如果该范围已关闭且最后一个元素未被遍历,则为1,如果该范围已打开,或该范围已关闭且所有元素都已被遍历,则为0 为什么需要这样的实现

  • 问题内容: Python文档明确指出了调用。但是似乎在许多情况下,情况恰恰相反。它何时何地发生的原因在哪里记录,如何确定我的对象或方法将被调用。 编辑:只是为了澄清,我知道在优选中调用,但是我不清楚为什么优先于调用,而后者是文档状态将发生的原因。 编辑:从马克·迪金森的答案和评论中,它看起来像是: 丰富的比较替代 是它自己的,以它的(以及类似的,等等) 如果左对象是内置类或新样式类,而右对象是其子