运算符.
算术运算符
+
、-
、*
、/
、%
、++
、--
赋值运算符
=
、+=
、-=
、*=
、/=
、%=
<<=
、>>=
、&=
、|=
、^=
比较(关系)运算符
==
、!=
、>
、<
、>=
、<=
、instanceof
逻辑运算符
- 逻辑:
&
、|
、!
、^
- 短路:
&&
、||
- 逻辑:
位运算符
- 操作的都是整型的数据
- 移位的步数有限制
- 比如说算术左移
1 << 31
结果会变成-2147483648
=-2
31
最高为变为了1,整个数变成了负数,由于这些数在计算机底层用补码
存储的(0b10000000 00000000 00000000 00000000
),所以求得的原码
就是-2147483648
- 算术右移
-1>>1
、-1>>2
。。。。=-1
- 所以说 在移位操作时,我们必须把数先换成 补码 再做操作 才能看出 原理
- 比如说算术左移
<< (算术左移|逻辑左移)
、>> (算术右移)
、>>> (逻辑右移 无<<<)
&
、|
、^
、~
三元(条件)运算符
- (条件表达式)? 表达式1 : 表达式2
- 条件表达式 = true ==> 表达式1
- 条件表达式 = false ==> 表达式2
- 所有三元运算符都可变为 if…else…语句
- 但是if…else…不一定能转为 三元; 因为if…else…中可能含有复杂的语句
- 表达式1 和 表达式2 结果类型要一直
- 如果表达式1为int型,表达式2位double型,表达式1的结果自动提升到double
优先级
类别 | 操作符 | 关联性 |
---|---|---|
后缀 | () [] . (点操作符) | 左到右 |
一元 | expr++ expr-- | 从左到右 |
一元 | ++expr --expr + - ~ ! | 从右到左 |
乘性 | * /% | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
关系 | > >= < <= | 左到右 |
相等 | == != | 左到右 |
按位与 | & | 左到右 |
按位异或 | ^ | 左到右 |
按位或 | | | 左到右 |
逻辑与 | && | 左到右 |
逻辑或 | | | | 左到右 |
条件 | ?: | 从右到左 |
赋值 | = + = - = * = / =%= >> = << =&= ^ = | = | 从右到左 |
逗号 | , | 左到右 |
运算符获得小知识点(之前未注意的).
使用赋值运算符类型不会改变(自增自减也不会)
short num = 2; num += 1; // num = 3 // 如果不使用 short tmp = 2; tmp = tmp + 1;//编译通不过
自增运算符小练习
int n = 10;
n += (n++) + (++n) // n = ?
n = n + n++ + ++n;
n = 10 + 10 + 1+10+1 = 32
交换两个数(按位异或)
int a = 1; int b = 2; System.out.println("原 a = " + a + "; b = " + b); //方法一:定义临时变量 //好处:①对于任何类型都可以 //推荐使用 int tmp = a; a = b; b = tmp; System.out.println("方法一 a = " + a + "; b = " + b); //方法二: 先加,后减 //好处:无需定义临时变量 //弊端:①相加可能会超出数的存储范围 ②只适用于 数值类型 a = a + b; b = a - b; a = a - b; System.out.println("方法二 a = " + a + "; b = " + b); //方法三: 异或 //好处:无需定义临时变量 //弊端:①只适用于 数值类型 a = a ^ b; b = a ^ b; a = a ^ b; System.out.println("方法三 a = " + a + "; b = " + b);
补充.
(他讲的还是有问题的 逻辑移位 其实是无符号的 不存在负数).
逻辑左移=算数左移,右边统一添0
逻辑右移,左边统一添0
算数右移,左边添加的数和符号有关