Java中(a == (a = b))是否存在未定义行为?赋值执行时机解析
Java赋值操作的执行时机与表达式求值规则
这种行为是Java语言规范明确定义的标准行为,和编译器无关,所有符合规范的Java编译器都会输出相同结果。
核心规则:表达式操作数的求值顺序是严格从左到右
Java规范规定,表达式中所有操作数的求值顺序是从左到右,优先级和括号仅决定运算的结合方式,不会改变操作数的求值顺序。
拿你给出的代码举例:
int a = 2; System.out.println(a == (a = 2*a+1)); System.out.println(a);
执行过程是:
- 先求值
==左侧的a,此时a的值为2; - 再求值
==右侧的括号内表达式a = 2*a+1:- 先计算
2*a+1,此时a还是初始的2,结果为2*2+1=5; - 将5赋值给
a,赋值表达式的返回值为5;
- 先计算
- 最后比较左侧的2和右侧的5,结果为
false; - 最后输出
a的值,此时a已经被修改为5。
对比自增操作的逻辑
你提到的a == (a++)和a == (++a)的结果差异,本质上和赋值操作遵循同一套求值规则:
a == (a++):先求值左侧的a(比如初始值为2),再执行a++(返回2,同时a变为3),最终比较2 == 2,结果为true;a == (++a):先求值左侧的a(初始值为2),再执行++a(a变为3,返回3),最终比较2 == 3,结果为false。
括号在这里仅用于分组运算,不会改变“从左到右求值”的核心规则。
再看a == (a = b)的场景
假设初始a = x,b = y,执行a == (a = b)时:
- 先求值左侧的
a,得到x; - 再执行
a = b,将a改为y,赋值表达式返回y; - 最后比较
x和y,结果取决于两者是否相等,不是先赋值再比较。
总结
- 赋值表达式
x = y的返回值是赋值完成后x的值; - 任何表达式的操作数都严格按从左到右的顺序求值,优先级和括号不改变这个顺序;
- 你看到的结果是Java规范的要求,不属于编译器特例。
内容的提问来源于stack exchange,提问作者Arxel
相关产品推荐
相关产品推荐

