java运算符优先级应靠分组理解而非死记,关键陷阱包括&&/||优先级低、==与=差异大、位运算符易误判、!优先级高于==、赋值运算符优先级最低;实操中一律加括号明确意图。

Java里运算符优先级怎么记才不翻车
Java的运算符优先级不是靠死记,而是靠“分组理解+少量特例”。你写 a + b * c 时根本不用查表,因为乘法天然比加法“绑定得更紧”——这和数学一致。但一旦混入位运算、赋值或三元操作,就容易出错。
真正危险的是这几处:
- && 和 || 的短路特性常被当成“优先级高”,其实它们优先级很低(比 == 还低)
- == 和 = 看起来像一对,但优先级天差地别,a = b == c 等价于 a = (b == c),不是 (a = b) == c
- 位运算符 &、^、| 的优先级夹在关系运算符和逻辑之间,a & b == c 实际是 a & (b == c),不是 (a & b) == c
建议做法:
- 涉及混合类型(比如算术+关系+逻辑),一律加括号,不赌记忆
- 写条件表达式时,把比较部分先用括号包住:if ((x > 0) && (y
- 用 IDE 的语法高亮观察结合方向(IntelliJ 会把 <code>a = b == c 中的 b == c 高亮为一个子表达式)
为什么 a == b & c 不等于 (a == b) & c
因为 &(按位与)的优先级低于 ==,所以 a == b & c 被解析为 a == (b & c),而不是你想的布尔比较结果再按位与。
常见错误现象:
- 本想判断 “a 等于 b,且 c 是 true”,却写了 a == b & c,结果编译报错(如果 c 是 boolean,b & c 类型不匹配)或逻辑错乱(如果 b、c 都是 int)
- 在权限掩码场景误用:flags & READ_PERMISSION == READ_PERMISSION 实际执行的是 flags & (READ_PERMISSION == READ_PERMISSION),后者恒为 flags & true → 编译失败
正确写法:
- 布尔逻辑用 &&/||,别用 &/|(除非明确需要非短路)
- 位运算场景必须加括号:(flags & READ_PERMISSION) == READ_PERMISSION
- 如果真要混合,优先级顺序参考:算术 > 移位 > 关系 > 位运算 > 逻辑 > 三元 > 赋值
!a == b 是什么鬼?为什么老出错
! 是一元运算符,优先级很高,但依然低于括号,且高于所有二元运算符。所以 !a == b 等价于 (!a) == b,不是 !(a == b)。
典型翻车现场:
- 检查对象非空且字段为某值,写成 !obj == null && obj.flag → 先算 !obj,直接编译失败(不能对引用取反)
- 判断布尔变量为 false 时,写 !flag == true,纯属冗余,且易读性差;更糟的是 !flag == false,等价于 flag == false,绕弯子
实操建议:
- 对 boolean 变量,直接用 flag 或 !flag,别跟 == true/false 拼
- 涉及 null 判断,写成 obj != null && obj.flag,清晰又安全
- 如果非要否定整个比较,就加括号:!(a == b),别省
赋值运算符 = 的优先级低到什么程度
= 是所有运算符里优先级最低的之一(仅高于 ,),这意味着它几乎最后才结合。所以 a = b == c 一定先算 b == c,再赋值给 a。
立即学习“Java免费学习笔记(深入)”;
容易被忽略的点:
- a = b = c 是合法的,因为赋值是右结合:a = (b = c),相当于先 b = c,再 a = b
- 但在条件中连写会误导人:if (a = b == c) 编译不过(返回 boolean,不能赋给 a),而 if ((a = b) == c) 才是想表达的“赋值后比较”
- 复合赋值如 += 优先级和 = 相同,a += b == c 解析为 a += (b == c)
防坑口诀:
- 赋值语句单独一行,别塞进 if/while 条件里(除非你真需要副作用)
- 真要用,就加括号明确意图:if ((result = compute()) != null)
- 开启编译器警告(如 -Xlint:assignment),让 javac 提醒你“赋值用在了布尔上下文”
优先级不是用来背的,是用来怀疑的。每次看到混合运算符,心里默念一句“它到底先算谁”,然后加括号——多敲两个字符,少调半小时 bug。










