本节目标
- 熟练掌握各类运算符使用
- 理解短路求值、位运算、移位运算
- 掌握三目条件运算符
- 了解运算符优先级,学会用括号消除歧义
1. 什么是运算符
运算符:对操作数执行运算的符号。 Java 运算符分类:算术运算符、关系运算符、逻辑运算符、位运算符、移位运算符、条件运算符。
int a = 10;
int b = 20;
a + b; // + 算术运算符
a < b; // < 关系运算符
2. 算术运算符
2.1 四则与取模 + - * / %
二元运算符,需要左右两个操作数。
int a = 20;
int b = 10;
System.out.println(a + b); //30
System.out.println(a - b); //10
System.out.println(a * b); //200
System.out.println(a / b); //2
System.out.println(a % b); //0 取模,求除法余数
⚠️重点坑点
-
int /int,结果仍然 int,直接舍弃小数部分,向下取整
int a = 3;
int b = 2;
System.out.println(a / b); //输出1,不是1.5
//想要小数结果,把其中一个操作数变成浮点
double d = a * 1.0 / b;
System.out.println(d); //1.5 -
除法、取模,右操作数不能为 0,运行抛出
ArithmeticException算术异常// int a = 1;
// int b = 0;
// System.out.println(a / b); //运行报错:/ by zero -
%也可以用于浮点数,但实际开发几乎不用,主要用于整数求余数。System.out.println(11.5 % 2.0); //1.5
-
两边类型不一致,小类型会自动提升为大类型。
System.out.println(1 + 0.2); //int提升double,输出1.2
2.2 复合赋值运算符 += -= *= /= %=
运算之后,把结果赋值给左边变量。
int a = 1;
a += 2; //等价 a = a + 2;
System.out.println(a); //3
a -= 1; //a = a -1
a *= 3; //a = a *3
a /= 3; //a = a /3
a %= 3; //a = a %3
✨重要特性:复合赋值运算符自带隐式强制类型转换
double a = 10.4;
int b = 10;
b += a; //✅ 自动强转,等价 b = (int)(b+a)
// b = b + a; //❌编译报错,b+a结果为double,不能直接赋值int
2.3 自增自减 ++ --
++变量 + 1;--变量‑1。
-
前置
++a:先自增,再使用值 -
后置
a++:先使用原值,表达式结束后再自增int a = 1;
a++; //后置++,单独使用,a变成2
System.out.println(a++); //输出2,打印完a变为3
System.out.println(a); //3++a;
System.out.println(++a); //前置++,先+1再输出,输出5
System.out.println(a); //5
注意:
- 单独使用时,前置和后置没有任何区别;
- 和打印、赋值混合使用,才会体现差异;
- 只能用于变量,不能用于常量 :
10++编译报错,常量不能修改。
3. 关系运算符
== != < > <= >=,运算结果一定是 boolean(true/false)。
int a = 10;
int b = 20;
System.out.println(a == b); //false 判断相等,两个等号!
System.out.println(a != b); //true 判断不相等
System.out.println(a < b); //true
System.out.println(a > b); //false
System.out.println(a <= b); //true
System.out.println(a >= b); //false
❗大坑:
=是赋值 ;==才是判断相等,千万不要写混。- 不能像数学那样连续写:
3 < a <5是错误 Java 语法。
需要写成:
a>3 && a<5
4. 逻辑运算符(高频重点)
&&逻辑与、||逻辑或、!逻辑非;操作数和结果都必须是 boolean。
4.1 && 逻辑与(并且)
全真才真,一假则假。

int a = 1;
int b = 2;
System.out.println(a == 1 && b == 2); //true
System.out.println(a == 1 && b >100); //false
System.out.println(a >100 && b ==2); //false
System.out.println(a>100 && b>100); //false
4.2 || 逻辑或(或者)
一真即真,全假才假。

System.out.println(a ==1 || b ==2); //true
System.out.println(a ==1 || b>100); //true
System.out.println(a>100 || b ==2); //true
System.out.println(a>100 || b>100); //false
4.3 ! 逻辑非(取反)
!true → false;!false → true

4.4 短路求值(面试考点)
-
&&:左边为 false,右边表达式直接不执行(短路),结果直接 false -
||:左边为 true,右边表达式直接不执行(短路),结果直接 true//10>20结果false,&&直接短路,10/0不会执行,不会报除零异常
System.out.println(10 > 20 && 10 / 0 == 0); //false
//10<20结果true,||直接短路,10/0不会执行
System.out.println(10 < 20 || 10 / 0 == 0); //true
区分
&、|(不短路) 当操作 boolean 时,&、|也可以做逻辑运算,但是不会短路,左右两边全部执行
// &不短路,10/0会执行,抛出异常
// System.out.println(10>20 & 10/0 == 0);
// |不短路,10/0会执行,抛出异常
// System.out.println(10<20 | 10/0 ==0);
开发逻辑判断优先用
&&、||,不要用&、|做逻辑。
补充:& | ^ ~操作整数的时候,是位运算符。
5. 位运算符
对二进制比特位 进行运算。& | ~ ^;~一元运算符,其余二元。
表格
| 运算符 | 含义 | 规则 | |
|---|---|---|---|
& 按位与 |
对应位都为 1,结果才是 1,否则 0 | 1&1=1;1&0=0;0&0=0 | |
| ` | ` 按位或 | 对应位都为 0 才得 0,否则为 1 | 1|1=1;1|0=1;0|0=0 |
^按位异或 |
对应位相同为 0,不同为 1 | 1^1=0;0^0=0;1^0=1 | |
~按位取反 |
0 变 1,1 变 0 | 一元运算符 |
int a = 10; // 1010
int b = 20; //10100
System.out.println(a & b);
System.out.println(a | b);
System.out.println(a ^ b);
int num = 0xf; //十六进制 0xf =15 二进制1111
System.out.printf("%x\n",~num);


小知识点:
0x开头代表十六进制数字;1 个十六进制位等价 4 个二进制位。- printf 中
%x以十六进制打印。 - 两个数字异或,
x ^ x =0;x ^0 =x。
6. 移位运算符
<<左移、>>右移、>>>无符号右移;针对二进制位运算。
<<左移:整体向左移动,左边丢弃,右边补 0。正数左移等价乘以\(2^n\)。
注意:正数左移可能把符号位移位,变成负数。
int a = 0x10;
System.out.printf("%x\n", a << 1);
-
>>算术右移 :整体向右移动,右边丢弃,左边补符号位(正数补 0,负数补 1)。正数右移等价除以\(2^n\)。int a = 0x10;
System.out.printf("%x\n", a >> 1); -
>>>无符号右移 :整体右移,右边丢弃,左边永远补 0,无视符号位。int a = 0xffffffff;
System.out.printf("%x\n", a >>>1);
小结(仅限正数)
- 左移
<< n等价 × \(2^n\) - 右移
>> n等价 ÷ \(2^n\) - 移位运算效率高于乘除,正数乘除 2 的幂可以用移位替代。
- 移动负数位,无意义。
7. 条件运算符(三目运算符)
Java唯一三目运算符
表达式1 ? 表达式2 : 表达式3
逻辑:
-
表达式1结果为true,执行返回表达式 2 结果; -
表达式1结果为false,执行返回表达式 3 结果。//求两个数最大值
int a =10;
int b =20;
int max = a > b ? a : b;
System.out.println(max);
⚠️注意事项
-
表达式 2、3 尽量类型一致,可以隐式转换也可以编译通过。
// int c = a>b ? 1 : 2.0; //返回值提升为double,不能直接赋值int
-
三目运算符不能单独当语句,运算结果必须接收 / 打印。
// a>b ? a : b; //编译报错,不是语句
8. 运算符优先级
运算符有优先级,* /高于+ -。
不建议死记优先级!代码有歧义直接加括号,可读性最重要。
错误示例(优先级坑)
int a = 10;
int b = 20;
int c = a + (b - a) >> 1;
// 等价 (a + (b‑a)) >>1 → 20 >>1 =10
//加上括号消除歧义,推荐写法
int d = a + ((b - a) >> 1);
📝本篇考点总结
int/int舍弃小数;除数不能为 0,会抛出算术异常。- 复合赋值运算符
+=自带隐式强制转换。 - 前置
++先加再用;后置++先用再加;只能用于变量。 - 关系运算符
==判断相等,不要和赋值=混淆;不能连续写数学不等式。 && ||支持短路求值;& |做逻辑不会短路。- 位运算:
& | ^ ~对二进制位操作;x^x=0。 - 移位:
<<左移;>>带符号右移;>>>无符号右移。正数移位等价乘除 2 的 n 次方。 - 三目运算符
条件 ? 表达式1 :表达式2,结果必须被接收,不能独立语句。 - 记不住运算符优先级就加括号,优先保证可读性。
面试小问答 Q:
System.out.println(10>20 && 10/0 == 0);会不会报错?为什么? A:不会。&&发生短路,左边10>20为 false,右侧10/0完全不执行。