java运算符优先级和结合性是编译器解析表达式的硬性依据:优先级决定高低顺序(如a+bc先算bc),结合性解决同级顺序(如a=b=c为右结合),括号是唯一可靠控制手段,常见坑包括位运算与比较混用、整数除法截断等。

Java 中运算符的优先级和结合性直接决定表达式中各部分的执行顺序,稍不注意就会得到和预期完全不同的结果。它们不是“可选规则”,而是编译器解析表达式的硬性依据。
优先级决定谁先算
优先级高的运算符总是先于优先级低的运算符执行,不管它们在表达式中出现的位置多靠前。比如:
-
a + b * c:哪怕
+写在前面,也一定先算b * c,再加a -
flag ? x + y : z == w:三元运算符
?:的优先级低于==,所以实际等价于flag ? x + y : (z == w),而不是(flag ? x + y : z) == w -
a & b == c:按位与
&的优先级低于==,实际是a & (b == c),通常这不是你想要的
结合性解决同级运算的顺序
当多个相同优先级的运算符连续出现时,结合性决定它们从左往右还是从右往左算:
-
从左到右(多数二元运算符):如
10 / 2 * 5先算10 / 2 = 5,再算5 * 5 = 25 -
从右到左(少数但关键):赋值类运算符(
=、+=)、三元运算符(?:)、一元运算符(++、--、!)都是右结合。例如a = b = c等价于a = (b = c);!a == b实际是(!a) == b,因为!优先级高于==,且右结合
括号是唯一可靠的控制手段
括号 () 拥有最高优先级,且可以嵌套。它不只是为了“让代码好看”,而是唯一能覆盖默认优先级的方式:
- 写
(a + b) * c就不会被误读为a + (b * c) - 逻辑表达式
a && b || c && d虽然按规则等价于(a && b) || (c && d),但显式加括号更清晰、更安全 - 涉及自增/自减时,如
i++ + ++i行为未定义(不同JVM可能不同),用括号也无法挽救——这时应避免单行混用,拆成两步更稳妥
容易踩坑的典型场景
这些地方优先级和结合性常被忽略,导致隐蔽错误:
-
整数除法提前截断:在
x * (y / x)中,若y / x是整数除法,会先丢掉小数,再乘;而(x * y) / x可能保留精度(前提是不溢出) -
负号 vs 减号:
-5 * 2是一元负号作用于 5,再乘 2;但a - b * c是减法,不是负号,二者语义不同 -
位运算和比较混用:像
if (flags & MASK == 0)实际是if (flags & (MASK == 0)),必须写成if ((flags & MASK) == 0)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











