算术运算符
加 减 乘 除 取余
取模运算,余数的符号跟被除数符号相同
public static void main(String[] args) {System.out.println(10 / 4); // 2 注意除法计算结果,因为都为整数,所以结果2.5会取整System.out.println(10.0 / 4); //2.5double d = 10 / 4;System.out.println(d); // 2.0}
@Testpublic void test_9() {System.out.println(5 % 2); //1System.out.println(5.0 % 2); //1.0 求余运算也会类型提升System.out.println(-5 % 2); //-1 结果的符号和被除数的符号一致//公式: a%b = a-a/b *b =》 -5%2 = -5-(-5)/2*2 = -5 -(-2)*2 = -5 + 4 = -1System.out.println(5 % -2); //1System.out.println(-5 % -2); //-1}
public class Test17 {public static void main(String args[]) {int x = -5;int y = -12;System.out.println(y % x); // -2 取模运算,余数的符号跟被除数符号相同//无论是正数还是负数,在取余运算时都有://被除数=商×除数+余数,所以-12=2×(-5)+(-2),-12是被除数,-5是除数,2是商,余数是-2。}}
自增自减
n++ ,++n,n—,—n
@Testpublic void test_9() {int a = 5;int b = a++; //先赋值后自增自减System.out.println(a); //6System.out.println(b); //5int a1 = 5;System.out.println(a1++); //5}
@Testpublic void test_9() {int a = 5;int b = ++a; //先自增自减后赋值System.out.println(a); //6System.out.println(b); //6int a1 = 5;System.out.println(++a1); //6}
public static void main(String[] args) {int i = 1;i = i++; // temp =i; i=i+1; i=tempSystem.out.println(i); //1int j = 1;j = ++j; // j=j+1; temp=j; j=tempSystem.out.println(j);//2}
//https://www.bilibili.com/video/BV1xt411S7xypublic static void main(String[] args) {int i = 1;i = i++; // i =1int j = i++; //j=1, i=2int k = i + ++i * i++; // 2 + 3 * 3System.out.println("i=" + i);System.out.println("j=" + j);System.out.println("k=" + k);}
关系运算符
大于> 大于等于>= 小于< 小于等于<= 等于== 不等于!=
关系运算符的运行结果是布尔值。
逻辑运算符
&& 与 ||或 !非
操作数只能是布尔值。
& (和 | 是位运算,可以进行逻辑运算。
&& 短路与, & 逻辑与。
区别:逻辑运算符有短路效果,位运算符不具有短路效果。
- 单个的逻辑运算符会将左右两个表达式都进行运算得出布尔值,再进行运算。
- ‘短路与’&& 若左边表达式为false则不会对右边的表达式进行判断,因为结果必为false;
- ‘短路或’|| 若左边表达式结果为true则不会对右边的表达式进行判断,因为结果必为true。

public class Test13 {private static int j = 0;private static Boolean methodB(int k) {j += k;return true;}public static void methodA(int i) {boolean b;// 对于boolean值,按位操作与逻辑操作有相同的结果,但是不会发生“短路”。b = i < 10 | methodB(4); //不会编译错误,这里是给b赋值,而不是访问bb = i < 10 || methodB(8); //短路或 || 如果结果确定,不继续计算}public static void main(String args[]) {methodA(0);System.out.println(j); //4}}
扩展赋值运算符
+= -+ = /= %=
例如:a+=b ==> a = a +b
*注意:扩展运算法会有隐式强转
@Testpublic void test_9() {short n = 5; // 因为5在short的范围内,不会报错n = n + 3; //编译报错, int转shortSystem.out.println(n);}@Testpublic void test_9() {short n = 5; // 因为5在short的范围内,不会报错n += 3; //这里会有一个隐式强转 (short)(n+3)System.out.println(n);}
条件运算符
表达式一 ? 表达式二 : 表达式三
表达式一运算的结果是布尔值
表达式二和表达式三要求 类型相符
表达式一的结果为true,就执行表达式二
表达式一的结果为false,就执行表达式三
@Testpublic void test_9() {Object object = true ? "" : new Object(); //其实这样也可以double v = true ? 2 : 2.2;//int v2 = true ? 2 : 2.2; //编译报错,2.2不能自动转为int}
位运算符
与& 或 | 非~ 异或 ^ 左移<< 右移>> 无符号右移>>>
按位运算符
- & 按位与 规则:两个同为1的时候才为1。
- | 按位或 规则:两个只要有一个为1就为1。
- ^ 按位异或 规则:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
- ~ 取反 规则:1 变0, 0变1 (单目运算符)
右移 规则:让操作数除以2的n次幂,n就是移动的位数,左边空出的位置用符号位的值补全
- << 左移 规则:让操作数乘以2的n次幂,n就是移动的位数
无符号右移 规则:让操作数除以2的n次幂,n就是移动的位数, 左边空出的位置用0补齐
在进行位运算的时候要把数据转换成二进制位,并且全部都是二进制的补码形式。
~ 取反
对3进行取反位运算:~3
3是正数,原码、反码、补码是一样的。
3的补码: 0b00000000 00000000 00000000 00000011
取反~3: 0b11111111 11111111 11111111 11111100 (此时是补码,补码是原码取反加1来的,现在是减1取反)
求原码-1:0b11111111 11111111 11111111 11111011 (求原码取反的时候,符号位不需要取反)
求原码取反:0b10000000 00000000 00000000 00000100 (此时是原码) -4 给人类显示的是原码
@Testpublic void test_8() {System.out.println(~3); //-4}
^ 按位异或
一个数据对相同的数据异或两次其值不变。
a^b^b = a
@Testpublic void test_8() {int a =3;int b =4;System.out.println(a^b^b); //3}
通过异或实现两个变量交换,不需要第三个变量
@Testpublic void test_8() {//一个数据对相同的数据异或两次其值不变。/*a = a ^ b;b = a ^ b; => a^b^b的结果就是a, 此时把a的值赋给ba = a ^ b; => a^b^a(因为现在的b其实是a)的结果就是b, 此时把b的值赋给a=> a^b^a^b^b => a^a^b => b*/int i = 10;int j = 20;i = i ^ j;j = i ^ j;i = i ^ j;System.out.println(i); //20System.out.println(j); //10}
>> 和 <<
往左移动两位,右边就空出两位,左边移动的两位就被挤掉了,右边空出的两位用0补全;
往右移动两位,左边就空出两位,右边的两位就被挤掉了,左边空出的两位用符号位的值填充(符号位是1就填充1,是0就填充0);
@Testpublic void test_9() {int i = 3<<4; // 3*2^4System.out.println(i); //48int j = 3>>4; // 3/2^4System.out.println(j); //0int k = 35>>4; // 35/2^4System.out.println(k); //2int l = -35>>4; // 35/2^4System.out.println(l); //-3}
-35的原码:10000000 00000000 00000000 00100011
-35的反码:11111111 11111111 11111111 11011100
-35的补码:11111111 11111111 11111111 11011101
-35的补码右移4位:1111 11111111 11111111 11111111 1101
减1: 1111 11111111 11111111 11111111 1100
取反:1000 00000000 00000000 00000000 0011
>>> 无符号右移
往右移动两位,左边就空出两位,右边的两位就被挤掉了,左边空出的两位用0填充。
对于正数,>> 和 >>>的结果是一样的。
对于负数,>> 和 >>>的结果是不一样的, >>>会变为正数。
public void test_9() {int k = 35>>>4; // 35/2^4System.out.println(k); //2int l = -35>>>4; // 35/2^4System.out.println(l); //268435453System.out.println(0b00001111111111111111111111111101); //268435453}
-35的原码:10000000 00000000 00000000 00100011
-35的反码:11111111 11111111 11111111 11011100
-35的补码:11111111 11111111 11111111 11011101
-35的补码右移4位:0000 11111111 11111111 11111111 1101 (此时是补码,但是是正数,原码和补码一样)
