Appearance
5.6 运算符优先级
运算符优先级的概念
运算符优先级决定了表达式中不同运算符的计算顺序。在 Java 中,不同的运算符有不同的优先级,优先级高的运算符会先于优先级低的运算符执行。
运算符优先级表
以下是 Java 中运算符的优先级从高到低的顺序:
| 优先级 | 运算符 | 描述 | 结合性 |
|---|---|---|---|
| 1 | () | 括号 | 从左到右 |
| 2 | ++ -- ! ~ + - | 一元运算符(自增、自减、逻辑非、按位非、正、负) | 从右到左 |
| 3 | * / % | 乘法、除法、取模 | 从左到右 |
| 4 | + - | 加法、减法 | 从左到右 |
| 5 | << >> >>> | 位移运算符 | 从左到右 |
| 6 | < <= > >= instanceof | 关系运算符 | 从左到右 |
| 7 | == != | 等于、不等于 | 从左到右 |
| 8 | & | 按位与 | 从左到右 |
| 9 | ^ | 按位异或 | 从左到右 |
| 10 | ` | ` | 按位或 |
| 11 | && | 逻辑与 | 从左到右 |
| 12 | ` | ` | |
| 13 | ?: | 三元运算符 | 从右到左 |
| 14 | = += -= *= /= %= <<= >>= >>>= &= ^= ` | =` | 赋值运算符 |
运算符优先级的应用
示例 1:算术运算符的优先级
java
public class ArithmeticPrecedenceExample {
public static void main(String[] args) {
int a = 10;
int b = 5;
int c = 3;
// 乘法优先于加法
int result1 = a + b * c; // 先计算 b * c = 15,再计算 a + 15 = 25
System.out.println("a + b * c = " + result1); // 输出 25
// 使用括号改变优先级
int result2 = (a + b) * c; // 先计算 a + b = 15,再计算 15 * c = 45
System.out.println("(a + b) * c = " + result2); // 输出 45
}
}示例 2:混合运算符的优先级
java
public class MixedPrecedenceExample {
public static void main(String[] args) {
int a = 10;
int b = 5;
int c = 3;
int d = 2;
// 复杂表达式的计算顺序
int result = a + b * c - d / 2;
// 计算顺序:b * c = 15, d / 2 = 1, a + 15 = 25, 25 - 1 = 24
System.out.println("a + b * c - d / 2 = " + result); // 输出 24
// 使用括号明确计算顺序
int result2 = (a + b) * (c - d) / 2;
// 计算顺序:a + b = 15, c - d = 1, 15 * 1 = 15, 15 / 2 = 7
System.out.println("(a + b) * (c - d) / 2 = " + result2); // 输出 7
}
}示例 3:逻辑运算符的优先级
java
public class LogicalPrecedenceExample {
public static void main(String[] args) {
int a = 10;
int b = 5;
int c = 3;
// 逻辑与优先于逻辑或
boolean result1 = a > b || b < c && a > c;
// 计算顺序:b < c = false, false && a > c = false, a > b = true, true || false = true
System.out.println("a > b || b < c && a > c = " + result1); // 输出 true
// 使用括号改变优先级
boolean result2 = (a > b || b < c) && a > c;
// 计算顺序:a > b = true, true || b < c = true, true && a > c = true
System.out.println("(a > b || b < c) && a > c = " + result2); // 输出 true
}
}结合性
结合性决定了当多个优先级相同的运算符连续出现时的计算顺序。
从左到右结合
大多数运算符都是从左到右结合的,例如:
java
int result = a + b + c; // 等同于 (a + b) + c从右到左结合
少数运算符是从右到左结合的,例如:
java
int result = a = b = c; // 等同于 a = (b = c)示例:结合性的应用
java
public class AssociativityExample {
public static void main(String[] args) {
// 从左到右结合
int a = 10;
int b = 5;
int c = 3;
int result1 = a + b - c; // 等同于 (a + b) - c
System.out.println("a + b - c = " + result1); // 输出 12
// 从右到左结合
int x = 10;
int y = 5;
int z = 3;
x = y = z; // 等同于 x = (y = z)
System.out.println("x = " + x + ", y = " + y + ", z = " + z); // 输出 x = 3, y = 3, z = 3
// 三元运算符的结合性
int num1 = 10;
int num2 = 5;
int num3 = 3;
int max = num1 > num2 ? num1 > num3 ? num1 : num3 : num2 > num3 ? num2 : num3;
// 等同于 num1 > num2 ? (num1 > num3 ? num1 : num3) : (num2 > num3 ? num2 : num3)
System.out.println("Max: " + max); // 输出 10
}
}运算符优先级的最佳实践
- 使用括号:当表达式复杂时,使用括号来明确计算顺序,提高代码可读性
- 理解优先级:了解常见运算符的优先级,避免因优先级问题导致的错误
- 测试表达式:对于复杂的表达式,进行测试以确保计算结果符合预期
- 代码可读性:优先考虑代码可读性,而不是依赖运算符优先级
常见问题
1. 优先级错误
症状:表达式的计算结果不符合预期
解决方案:使用括号来明确计算顺序
2. 结合性错误
症状:连续使用相同优先级的运算符时,计算顺序不符合预期
解决方案:了解运算符的结合性,或使用括号来明确计算顺序
3. 复杂表达式
症状:表达式过于复杂,难以理解
解决方案:将复杂表达式分解为多个简单表达式,提高代码可读性
总结
运算符优先级决定了表达式中不同运算符的计算顺序,优先级高的运算符会先于优先级低的运算符执行。结合性决定了当多个优先级相同的运算符连续出现时的计算顺序。
在编写 Java 代码时,应该:
- 了解常见运算符的优先级
- 对于复杂的表达式,使用括号来明确计算顺序
- 优先考虑代码可读性,而不是依赖运算符优先级
- 测试复杂表达式的计算结果,确保符合预期
通过合理使用运算符优先级和括号,可以编写更加清晰、正确的 Java 代码。
