1. 算数运算符
1.1 二元运算符(两个操作数)的算数运算符
操作符 | 描述 |
---|---|
+ | 求和 |
- | 求差 |
* | 求积 |
/ | 求商 |
% | 求余 |
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 20;
int b = 12;
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);
}
}
运行结果
- a / b = 1.67 但是a是int b也是int 结果也是int,所以是等于1
- a % b是取余,也就是取余数 20 / 12的余数是8,所以是8
1.2 一元运算符(一个操作数)的算数运算
操作符 | 描述 |
---|---|
++ | 递增,变量值+1 |
– | 递减,变量值-1 |
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 10;
a++;
System.out.println("a = " + a);
int b = 20;
b++;
System.out.println("b = " + b);
}
}
运行结果
运行结果都一样,此时我们可以得出一个结论,当递增递减单独作为一条语句时,++在前在后,运行结果都不变
是不是代表++在前面和后面都一样呢 我们可以在看代码
public class TestOperator {
public static void main(String[] args) {
int result = 0;
int a = 10;
result = a++;
System.out.println("result = " + result);
System.out.println("a = " + a);
int b = 10;
result = ++b;
System.out.println("result = " + result);
System.out.println("b = " + b);
}
}
运行结果
可以看到,此时结果改变了,可以得出结论是,如果递增递减运算符不作为单独的语句时,那么++、–在前在后就会有区别
- 如果++、–在前,则先执行++、–,再去执行其他
- 如果++、–在后,则先执行其他,再执行++、–
2. 赋值运算符
操作符 | 描述 |
---|---|
= | 直接赋值 |
+= | 求和后赋值 |
-= | 求差后赋值 |
*= | 求积后赋值 |
/= | 求商后赋值 |
%= | 求余后赋值 |
代码举例:
public class TestOperator {
public static void main(String[] args) {
int a = 10;
System.out.println(a);
a += 10;
System.out.println(a);
a -= 10;
System.out.println(a);
a *= 10;
System.out.println(a);
a /= 10;
System.out.println(a);
a %= 10;
System.out.println(a);
}
}
运行结果:
与完整表达式的区别
public class TestOperator {
public static void main(String[] args) {
short a = 20;
a += 10; //JVM会实现隐式的类型转换
short b = 20;
b = (short)(b + 10);
System.out.println(a);
System.out.println(b);
}
}
如果我们不强制类型转换short
此时可以发现这里出现了报错,原因是类型不匹配,而为什么+=没问题呢,原因是因为JVM会帮我们实现隐式的类型转换,而完整的表达式不会,需要我们手动的进行强制类型转换
3. 关系运算符
关系运算符就是两个操作数进行比较,结果是布尔类型
表示两个操作数之间或者两个表达式之间的关系是否成立
操作符 | 描述 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 88;
int b = 99;
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);
System.out.println(a != b);
}
}
运行结果
4. 逻辑运算符
两个boolean类型的操作数或表达式进行逻辑比较
- 关系运算符的结果就是boolean类型,所以我们可以用关系运算来进行逻辑比较
操作符 | 语义 | 描述 |
---|---|---|
& | 逻辑与(并且) | 要求两个或者多个条件同时成立 则最终结果为true |
&& | 短路与(并且) | 要求两个或者多个条件同时成立 则最终结果为true |
| | 逻辑或(或者) | 要求两个或者多个条件 至少有一个成立 则最终结果为true |
|| | 短路或(或者) | 要求两个或者多个条件 至少有一个成立 则最终结果为true |
! | 非(取反) | 真即是假,假即是真 |
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 88;
int b = 99;
int c = 111;
System.out.println(a > b && b < c);
System.out.println(a > b & b < c);
System.out.println(a < b && b < c);
System.out.println(a < b & b < c);
System.out.println("----------------------------");
System.out.println(a > b || b < c);
System.out.println(a > b | b < c);
System.out.println(a > b || b > c);
System.out.println(a > b | b > c);
System.out.println("----------------------------");
System.out.println(!(a < b));
System.out.println(!(a > b));
}
}
运行结果
从上图可知,&
和&&
的运算结果是相同的,|
和||
的运算结果也是相同的,那为什么不直接使用一个呢
那是因为&&短路效果,所以他叫做短路,&&不仅有&效果之外,还能有短路的效果,||和|的关系亦然
代码举例(用逻辑或举例)
public class TestOperator {
public static void main(String[] args) {
int a = 10;
int b = 11;
int c = 13;
System.out.println(a > b & ++b > c);
System.out.println(b);
b = 11; //初始回原值便于观察
System.out.println(a > b && ++b > c);
System.out.println(b);
}
}
运行结果
可以看到逻辑与的b值是变了的,而短路与的b值没变,得出结论
- 逻辑与他没有短路效果,即使第一个条件(a>b)不成立,也会继续执行判断第二个条件是否成立,即使第一个条件已经不满足逻辑与的要求
- 短路与有短路效果,当第一个条件(a>b)不成立,已经不满足逻辑与的要求,则后续的条件不执行,所以b值不变
逻辑或的判断同理,这里不具体阐述
5. 三目运算符
根据布尔表达式的结果选择执行结果1或者结果2,同时可以把结果1or结果2赋值给变量
操作符 | 语义 | 描述 |
---|---|---|
? : | 布尔表达式?结果1:结果2 | 当表达式结果为真,则结果1 当表达式结果为假,则结果2 |
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 0;
c = a > b ? a : b;
System.out.println(c);
}
}
运行结果
6. 位运算符
位运算是对整数的二进制进行运算
运算符 | 运算 | 作用 |
---|---|---|
<< | 左移 | 左移几位表示乘以2的几次方,可能会出现负数 |
>> | 右移 | 右移几位表示除以2的几次方 如果最高位是1则空缺位补1 如果最高位是0则空缺位补0 |
>>> | 无符号右移 | 不管最高位是0还是1 空缺位统一以0填充 最终结果都是正数 |
& | 与运算 | 两个相同二进制位进行与运算 两者为1则结果为1 一个为0则结果为0 |
| | 或运算 | 两个相同二进制位进行或运算 一个为1则结果为1 两者为0则结果为0 |
^ | 异或运算 | 两个相同二进制位进行异或运算 相同为0 相异为1 |
~ | 取反运算 | 包括符号位取反 0取反为1 1取反为0 |
6.1 左移运算符
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 1;
System.out.println(a << 1);
System.out.println(a << 2);
System.out.println(a << 3);
System.out.println(a << 31);
}
}
运行结果
得出结论
- 左移几位表示乘以2的几次方,可能会出现负数
6.2 右移运算符
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 8;
System.out.println(a >> 1);
System.out.println(a >> 2);
int b = -8;
System.out.println(b >> 1);
System.out.println(b >> 2);
}
}
- 假设内存是1个字节8个位进行画图,实际上int有32个位,为了方便演示则使用8位
- a >> 1
整体往右移,右移完后,右边的0抛弃,左边补上0
- b >> 1
这是-8的补码,转换为补码之后,对于左边为什么是补1就会有很直观的理解
整体往右移,右移完后,右边的0抛弃,左边补上1
得出结论
- 右移几位表示除以2的几次方
- 如果最高位是1则空缺位补1
- 如果最高位是0则空缺位补0
6.3 无符号右移
假设内存是1个字节8个位进行画图,实际上int有32个位,为了方便演示则使用8位,为什么不用byte a = -8呢,这样会不会范围就是127以内了,其实并不是,上一篇文章提到自动类型转换,因为-8是int类型,赋给了a之后会自动提升为int类型,所以他的取值范围是int的取值范围,而不是byte的取值范围,所以我们只能假设,或者是强制类型转换为byte类型
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = -8;
System.out.println(a >>> 1);
System.out.println(a >>> 2);
}
}
运行结果
演示
int有32位,也就是32个位整体往右移一位,最右边的0抛弃,最高位补0,所以a>>>1的结果是2147483644
6.4 与运算符
代码举例
package com.csdn.code.day3;
public class TestOperator {
public static void main(String[] args) {
int a = 12;
int b = 24;
System.out.println(a & b);
}
}
运行结果
两个相同二进制位进行与运算 两者为1则结果为1 一个为0则结果为0
6.5 或运算符
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 12;
int b = 24;
System.out.println(a | b);
}
}
运行结果
两个相同二进制位进行或运算 一个为1则结果为1 两者为0则结果为0
6.6 异或运算符
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 12;
int b = 24;
System.out.println(a ^ b);
}
}
运行结果
两个相同二进制位进行异或运算 相同为0 相异为1
6.7 取反运算符
代码举例
public class TestOperator {
public static void main(String[] args) {
int a = 12;
int b = -8;
System.out.println(~a);
System.out.println(~b);
}
}
运行结果
以-8为例(包括符号位取反 0取反为1 1取反为0)