📚 目录
🔍 运算符分类概览
Java运算符
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
条件运算符
类型相关运算符
➕ 算术运算符
基础运算符表
运算符 | 描述 | 示例 | 备注 |
---|---|---|---|
+ | 加法 | a + b | 支持字符串拼接 |
- | 减法 | a - b | |
* | 乘法 | a * b | 注意数值溢出 |
/ | 除法 | a / b | int类型会整除 |
% | 取模 | a % b | 符号跟随被除数 |
++ | 自增 | a++ / ++a | 注意前置/后置差异 |
-- | 自减 | a-- / --a |
类型提升陷阱
int a = 5; int b = 2; System.out.println(a / b); // 输出2(整数除法) double c = 3 / 2; // 输出1.0(先做整数除法再转为double) double d = 3.0 / 2; // 输出1.5
🎚️ 关系运算符
比较运算符表
运算符 | 描述 | 示例 | 注意事项 |
---|---|---|---|
== | 等于 | a == b | 对象比较引用地址 |
!= | 不等于 | a != b | |
> | 大于 | a > b | 不支持布尔类型 |
< | 小于 | a < b | |
>= | 大于等于 | a >= b | |
<= | 小于等于 | a <= b |
对象比较陷阱
String s1 = new String("Java"); String s2 = new String("Java"); System.out.println(s1 == s2); // false(比较引用地址) System.out.println(s1.equals(s2)); // true(比较内容)
🧠 逻辑运算符
真值表对比
运算符 | 名称 | 示例 | 运算规则 |
---|---|---|---|
& | 逻辑与 | a & b | 全真为真(两个操作数都计算) |
| | 逻辑或 | a | b | 有真为真(两个操作数都计算) |
! | 逻辑非 | !a | 取反 |
&& | 短路与 | a && b | 左假即短路 |
|| | 短路或 | a || b | 左真即短路 |
短路特性示例
public boolean isValid(int value) { return value != 0 && (100 % value) == 0; // 避免除零异常 }
👁️ 神秘的位运算符
二进制操作
运算符 | 描述 | 示例 | 运算规则 |
---|---|---|---|
& | 按位与 | a & b | 同为1则1 |
| | 按位或 | a | b | 有1则1 |
^ | 按位异或 | a ^ b | 相同为0,不同为1 |
~ | 按位取反 | ~a | 0变1,1变0 |
<< | 左移 | a << b | 低位补0 |
>> | 右移 | a >> b | 正数补0,负数补1 |
>>> | 无符号右移 | a >>> b | 高位补0 |
实用技巧
// 判断奇偶 boolean isOdd = (num & 1) == 1; // 交换两个变量的值(不用临时变量) a ^= b; b ^= a; a ^= b; // 权限控制(位掩码) final int READ = 1 << 0; // 0001 final int WRITE = 1 << 1; // 0010 int permission = READ | WRITE;
🔄 赋值运算符
复合赋值示例
int a = 10; a += 5; // 等价于 a = a + 5 a <<= 2; // 等价于 a = a << 2 // 类型转换陷阱 byte b = 5; b += 10; // 合法(隐含类型转换) b = b + 10; // 编译错误(需要强制转换)
❓ 条件运算符(三目运算符)
高效选择示例
int score = 85; String result = score >= 60 ? "合格" : "不合格"; // 嵌套使用 String grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "D";
🏆 运算符优先级
金字塔优先级表(自上而下优先级递减)
最高:() [] . ++ -- ! ~ instanceof * / % + - << >> >>> < > <= >= == != & ^ | && || ?: 最低:= += -= *= /= %= ...
推荐写法
// 模糊优先级时使用括号明确 int result = a + (b * c) / (d << 1);
🚀 JDK新特性
1. switch表达式(JDK14+)
String weekday = switch(day) { case 1 -> "Monday"; case 2 -> "Tuesday"; default -> "Unknown"; };
2. 类型匹配运算符(JDK16+)
Object obj = "Hello Java"; if (obj instanceof String s) { // 直接类型转换 System.out.println(s.length()); }
⚠️ 典型陷阱
1. 自增运算的陷阱
int i = 5; int j = i++ + ++i; // 分解步骤: // temp = i (5) // i自增为6 // i再次自增为7 // j = 5 + 7 = 12
2. 浮点数比较
double d1 = 0.1 + 0.2; double d2 = 0.3; System.out.println(d1 == d2); // false // 正确比较方式:Math.abs(d1-d2) < 1e-6
⚡ 性能优化
-
位运算提速:
// 代替乘除法 int a = num << 1; // 等价于 num * 2 int b = num >> 1; // 等价于 num / 2
-
减少对象创建:
// 字符串拼接优化 String result = "ID:" + userId; // 低效方式(产生临时对象) StringBuilder sb = new StringBuilder().append("ID:").append(userId); // 高效方式
-
短路特性利用:
if (list != null && !list.isEmpty()) { // 避免NPE // ... }
🏆 最佳实践
-
复杂表达式拆分:
// 难以阅读 int result = a<<b | (c > d ? e : f^g); // 建议写法 int temp1 = a << b; int temp2 = (c > d) ? e : (f ^ g); int result = temp1 | temp2;
-
防御性编程:
// 除法运算前检查除数 double divide(int dividend, int divisor) { if (divisor == 0) throw new IllegalArgumentException(); return (double)dividend / divisor; }
-
类型安全原则:
// 强制转换前进行范围检查 byte convertToByte(int value) { if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { throw new ArithmeticException(); } return (byte)value; }