Java表达式的运算顺序由运算符优先级和结合性共同决定,优先级高的运算符会先参与运算,同优先级的运算符则根据结合性从左到右或从右到左执行,而括号可以强制改变默认的运算顺序。

Java运算符优先级总览
Java中的运算符按照优先级从高到低可以分为多个层级,以下是常见运算符的优先级排序:
| 优先级 | 运算符类型 | 具体运算符 | 结合性 |
|---|---|---|---|
| 1 | 括号、成员访问 | () [] . | 从左到右 |
| 2 | 一元运算符 | ++ -- + - ~ ! (数据类型) | 从右到左 |
| 3 | 算术乘除模 | * / % | 从左到右 |
| 4 | 算术加减 | + - | 从左到右 |
| 5 | 移位运算符 | << >> >>> | 从左到右 |
| 6 | 关系比较 | < > <= >= instanceof | 从左到右 |
| 7 | 相等比较 | == != | 从左到右 |
| 8 | 按位与 | & | 从左到右 |
| 9 | 按位异或 | ^ | 从左到右 |
| 10 | 按位或 | | | 从左到右 |
| 11 | 逻辑与 | && | 从左到右 |
| 12 | 逻辑或 | || | 从左到右 |
| 13 | 三元运算符 | ? : | 从右到左 |
| 14 | 赋值运算符 | = += -= *= /= %= &= |= ^= <<= >>= >>>= | 从右到左 |
基础运算顺序判断示例
我们通过一个包含多种运算符的表达式来演示默认优先级下的运算顺序:
public class OperatorOrderDemo {
public static void main(String[] args) {
int a = 5;
int b = 3;
int c = 10;
// 表达式包含乘法、加法、关系比较、逻辑与
boolean result = a * b > c && a + b < 10;
// 运算顺序:先计算a*b=15,a+b=8
// 再计算15>c(15>10为true),8<10为true
// 最后计算true && true,结果为true
System.out.println(result); // 输出true
}
}
括号策略的使用规则
当默认的优先级不符合我们的计算需求时,可以使用括号强制调整运算顺序,括号的优先级是最高的,会优先执行括号内的表达式。
括号改变运算顺序示例
还是上面的表达式,如果我们希望先判断a*b的结果是否大于c和a+b的和,就可以用括号调整:
public class BracketDemo {
public static void main(String[] args) {
int a = 5;
int b = 3;
int c = 10;
// 使用括号强制先计算a+b的结果
boolean result = a * b > c && (a + b) < 10;
// 这里括号不影响结果,因为+的优先级本来就低于*
// 换一个场景,希望先判断a*(b>c)是错误写法,因为b>c是布尔值不能和int相乘
// 正确的括号用法:如果要计算(a*b + c) * a
int num = (a * b + c) * a;
System.out.println(num); // 先计算a*b=15,15+10=25,25*5=125,输出125
}
}
括号使用的注意事项
- 括号必须成对出现,否则会编译报错
- 不要过度使用括号,不需要改变默认优先级的地方加括号会降低代码可读性
- 多层括号时从内层向外层依次计算,例如((a + b) * c) / d,先算a+b,再乘c,最后除以d
特殊场景的运算顺序判断
一元运算符的优先级
一元运算符的优先级高于算术运算符,例如自增运算符:
public class UnaryDemo {
public static void main(String[] args) {
int x = 2;
// ++x是前缀自增,先自增再参与运算,x先变成3,再计算3*4=12
int y = ++x * 4;
System.out.println(y); // 输出12
System.out.println(x); // 输出3
}
}
赋值运算符的结合性
赋值运算符是从右到左结合的,因此连续赋值时从最右侧开始计算:
public class AssignDemo {
public static void main(String[] args) {
int a, b, c;
// 从右到左赋值,先把5赋给c,再赋给b,再赋给a
a = b = c = 5;
System.out.println(a + " " + b + " " + c); // 输出5 5 5
}
}
常见错误与避坑建议
很多开发者会忽略逻辑运算符的短路特性,结合运算顺序时容易出错:
public class ShortCircuitDemo {
public static void main(String[] args) {
int m = 5;
// 因为m>10为false,&&短路,后面的m++不会执行
boolean res = m > 10 && m++ > 5;
System.out.println(res); // 输出false
System.out.println(m); // 输出5,m没有自增
}
}
建议在实际开发中,如果不确定运算符的优先级,或者表达式逻辑比较复杂,可以适当添加括号明确运算顺序,既避免错误,也能让代码逻辑更清晰,方便后续维护。