- 什么是运算符
运算符 :用来对**操作数 (变量 / 数值)**执行运算的符号Java 运算符 6 大分
- 算术运算符(做加减乘除数学运算)
- 关系运算符(比较大小,结果只能是 true/false 布尔值)
- 逻辑运算符(判断多个条件之间的关系)
- 赋值运算符(给变量赋值)
- 位运算符、移位运算符(操作二进制底层)
- 条件运算符 (三元运算符)
格式:条件 ? 值1 : 值2
如果条件成立取 值 1,否则取 值 2算术运算符
基本四则运算符 + - * / %
int a=20; int b=10; System.out.println(a+b); System.out.println(a-b); System.out.println(a*b); System.out.println(a/b); System.out.println(a%b);
二元运算符 :必须提供左右 2 个操作数,不能只写一边
整数除以整数 :
int / int结果一定是int,向下取整,小数直接舍弃
int a=3; int b=2; System.out.println(a/b); //结果应该是1.5,然而得到的是1,会向下取整,也就是舍弃掉小数 //想要得到小数结果,需要强制类型转换成浮点数类型 double d=a*1.0/b; System.out.println(d);除数不能为 0
/ 和 % 的右边不能写 0,否则抛出算术异常ArithmeticException: / by zero
// int a=1; // int b=0; //// System.out.println(a/b); // 除数不能为0,为0时,会抛出算术异常 // System.out.println(a%b);取模
%:支持小数运算,但开发几乎只用整数取模
System.out.println(10.0%3.0); //1.0类型自动提升 :两边运算类型不一样,小类型自动提升到大类型
System.out.println(1+0.2); //int(1) 提升为double 结果是1.2
增量运算符 += -= *= %=
运算结束后,直接把结果赋值给左边变量
格式:变量 运算符 = 值,等价于变量 = 变量 运算符 值
int a=1; a+=1; //等价a=a+1 System.out.println(a); int b=2; b-=1; //等价 b=b-1 System.out.println(b); int c=3; c*=2; //c=c*3 System.out.println(c); int d=4; d/=2; //d=d/2; System.out.println(d);自带强制类型转换
复合赋值运算符,会自动把结果转回左边变量的类型 ,不需要手动强转
double a=10.4; int b=10; // b+=a; //等价于 b=(int)(a+b); // System.out.println(b); // b=b+a; //编译报错,a(int)是小类型,会提升大类型(double) a+b 的结果是double ,把结果赋值给类型是int的会报错 //强制类型转换是可行的 -- > b=(int)(b+a);区别总结:
b += a:自带强制转换,double→int
b = b + a:无转换,右边运算结果为double,不能直接赋给int
自增
++/ 自减--运算符
核心定义
++:给变量的值 +1
--:给变量的值 -1
只能作用于变量,常量不能写 5++,常量值不能修改后置自增:a++
先使用变量原来的值,表达式结束后变量再加 1(先使用,后加1)
int a=1; a++; //2 System.out.println(a++); // 2 后置++ 是先使用后加1,先打印2,在加1 System.out.println(a); //3前置自增:++a
先给变量 + 1,然后再使用加完之后的值(先加一,后使用)
int a=3; ++a; //4 System.out.println(++a); //5 前置++ 是先使用后加1,先加1,后打印5 System.out.println(a);注意:
a)单独一行使用(a++; / ++a;):前置 ++ 和后置 ++ 效果完全一样,没有区别
b)放在打印、赋值等表达式里(混合使用):
前置 ++a:先加 1,后用值
后置 a++:先用原值,后加 1
c)只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改自减--
规则和
++一模一样,只是变成减 1:
a--:先用原值,再减 1
--a:先减 1,再用新值关系运算符
- 6 个关系运算符列表
关系运算的结果一定是布尔值:true(真) / false(假)
//关系运算符 == != < > <= >= int a=10; int b=20; System.out.println(a==b); //flase System.out.println(a!=b); //true System.out.println(a<b); //true System.out.println(a>b); //flase System.out.println(a<=b); //true System.out.println(a>=b); //flase坑点
= 和 == 不一样
=:赋值运算符 ,作用是把右边的值给到左边变量
==:关系运算符 ,用来判断左右两边数值是否相等
a = 10; // 赋值,把10放进变量a a == 10; // 判断,a的值是不是等于10不能像数学那样连写判断
错误写法:3 < a <5
正确写法:(用来逻辑运算符)
a > 3 && a < 5逻辑运算符
逻辑与 &&
语法规则:表达式1 && 表达式2,左右表达式必须是boolean类型的结果
两个表达式都为真,结果才是真,只要有⼀个是假,结果就是假
口诀: 全真才真,一假则假
//逻辑&& 全真则真,一假则假 int a=1; int b=2; System.out.println(a==1&&b==2); //true && true --> true System.out.println(a==1&&b>100); //true && false --> false System.out.println(a>100&&b==2); //false && true --> false System.out.println(a>100&&b>100); //false && false --> false
逻辑 ||
- 语法规则:
表达式1 || 表达式2,左右表达式必须是boolean类型的结果- 或运算,有真即真,全假才假
逻辑非 !
- 语法规则:! 表达式
- 真变假,假变真
System.out.println(!true); System.out.println(!false); int a=5; System.out.println(a>3); //true System.out.println(!(a>3)); //false System.out.println(a<1); //false System.out.println(!(a<1)); //true
短路求值
短路运算符:
&&(短路与)、||(短路或)
a)&& 短路规则(一假则假)
左边结果为 false → 直接得出最终结果 false, 右边代码不会执行 (短路)
// 短路 或 左边的为假,右边的不执行 -- > 短路 System.out.println((10>20 )&& (10 /0==0)); //false
10>20→ false ,触发短路,10 / 0不会运行,不会报除零异常,输出:false
b)|| 短路规则(一真则真)
左边结果为 true → 直接得出最终结果 true, 右边代码不会执行 (短路)
//短路与 左边为真,右边的就不执行 -- > 短路 System.out.println((10<20)||(10/0==0)); // true
10<20→ true ,触发短路,10 / 0不会运行,不会报除零异常,输出:true非短路运算符 :
&(与)、|(或)
//非短路运算符 //无论左右两边的结果如何,右边都会执行 System.out.println((10>20)&(10/0==0)); // 程序会抛异常 System.out.println((10<20)|(10/0==0)); // 程序会抛异常没有短路效果,无论左 边结果是什么, 左右两边代码都会执行
两条语句都会执行右边 10 / 0 ,除以 0 报错,程序抛出异常
总结
a)对于 && , 如果左侧表达式值为 false, 则表达式结果是 false,无需计算右侧表达式
b)对于 ||, 如果左侧表达式值为 true, 则表达式结果是 true, 无需计算右侧表达式
c)& 和 | 如果表达式结果为 boolean 时, 也表示逻辑运算. 但与 && || 相比, 它们不支持短路求值位运算符
知识点
- 最小存储单位 :字节 (byte),
1字节 = 8个二进制位(bit)
最小运算单位:比特位 (bit)- 位运算符是直接对数字二进制的每一位 进行计算
4 个位运算符:&(按位与) 、|(按位或) 、~(按位取反,一元运算符)、^(按位异或)&、|:
操作boolean → 逻辑运算,不支持短路
操作整数 (int/byte/short/long) → 位运算按位与
&
- 规则 :
二进制对应位,两个都为 1,结果才是 1;否则为 0- 例:
a=10,b=20
int a=10; int b=20; System.out.println(a&b); //结果为0
按位或
|
- 规则:两位都为 0,结果才是 0;否则为 1
int a=10; int b=20; System.out.println(a|b); //30
- 注意
当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算
当操作数为 boolean 的时候, 表示逻辑运算按位取反
~
- 一元运算符,规则:0 变 1,1 变 0
int a=0xf; System.out.printf("%x\n",~a);
- 注意
a)0x 前缀的数字为十六进制数字, 十六进制可以看成是⼆进制的简化表示方式,⼀ 个十六进制数字对应 4 个⼆进制位
b)0xf 表示 10 进制的 15, 也就是⼆进制的 1111
c)printf 能够格式化输出内容, %x 表示按照⼗六进制输出
d)\n 表示换行符按位异或
^
- 规则:二进制位相同得 0,不同得 1
int a=0x1; int b=0x2; System.out.println(a^b); System.out.printf("%x\n",a^b);
- 重要性质
x ^ x = 0--> 同一个数异或自己,结果是 0
x ^ 0 = x--> 一个数异或 0,等于本身
异或满足交换律:a^b = b^a- 例子:
5 ^ 5 = 0
5 ^ 0 = 5- 注意
如果两个数相同,则异或的结果为0移位运算
移位运算符:
<<(左移)、>>(算术右移)、>>>(无符号右移),操作二进制比特位左移
<<
- 规则:丢掉最左边位,右边补 0
int a=0x10; //16 System.out.println(a); //左移一位,相当于是乘以2 System.out.printf("%x\n",a<<1); //打印十六进制 0x20 (0010 0000) System.out.println(a<<1); //32
- 正数左移 N 位 ≈
原数 * 2ⁿ- 会丢弃符号位,正数左移有可能变成负数
算术右移
>>
- 规则 :
丢掉最右边位,左边补符号位:正数补 0,负数补 1- 正数右移 N 位 ≈ 原数 / 2ⁿ
负数右移,高位一直补 1,保持负数符号
//算术右移 int a=0x10; System.out.printf("%x\n",a>>1); //0001 0000 --> 0000 1000 得到ox8 System.out.println(a>>1); int b=0xffff0000; //负数 System.out.printf("%x\n",b>>1); //0xffff8000
无符号右移
>>>
- 规则:丢掉最右边位,左边永远补 0,不管正负
总结
- 正数
- 移位 CPU 效率高于乘除,乘除 2 的幂次可以用移位优化(只适合正数)
- 移位位数不能是负数,位数过大无意义
- 面试常考
>> 和 >>> 的区别:>>补符号位,>>> 一直补 0条件运算符
- 语法格式
表达式1 ? 表达式2 : 表达式3
表达式 1 :条件,结果必须是布尔值true/false
a)如果表达式 1 为 true → 整个三目运算结果 = 表达式 2 的值
b)如果表达式 1 为 false → 整个三目运算结果 = 表达式 3 的值
// 条件运算符 int a=10; int b=20; int max=a>b? a:b; System.out.println(max); // if - else int max1=0; if(a>b) { max1=a; } else { max1=b; } System.out.println(max1);
注意
a)表达式2和表达式3的结果要是同类型的,除非能发生隐式类型转换
二者尽量为同一类型;允许隐式自动类型转换
// 隐式类型转换 int a =30; int b=20; // int c=a>b?1:2.0; // 编译报错, int 会发生隐式类型转换 ,转换成double,double的值赋值给int,不行 double d=a>b?1:2.0; System.out.println(d); //此法,可行三目会把两个结果做类型统一,1会提升为double,整体结果是 double ,不能直接赋给 int 变量
b)三目运算符不能单独作为语句,运算结果必须被使用(赋值、打印等)
int a = 10; int b = 20; a > b ? a : b;运算符的优先级
知识点
- 运算符优先级决定表达式运算先后顺序:乘除 > 加减 > 移位
- 复杂表达式直接用括号即可
- 移位运算符优先级比加减低
例子
int a=10; int b=20; int c =a+(b-a)>>1; //由于 加法运算符比移位运算符 优先级高,括号算完后,就算加法了,最后算右移 System.out.println(c); //1 0运算优先级:+ 高于 >>(右移运算符)
先算括号内:b‑a = 20‑10 = 10
再算加法:
a + 10 = 10 +10 = 20最后做右移
>>1:20 >> 1 = 10
2.
3.
int a=10; int b=20; int c=a+((b-a)>>1); System.out.println(c); //15运算步骤:
b‑a = 10
10 >>1 =5
a +5 = 10+5 =15




















