(1)算数运算符
+ 加
- 减
* 乘
/ 除
% 取余
++ 自加
-- 自减
-
+ 运算符的重载
如果 + 运算符的前或后参与运算的有字符串时,则 + 作为字符串拼接符进行运算
-
自加和自减运算符:
++a、a++ 和 --a、a-- 等价于 a = a + 1 和 a = a - 1;
在参与运算时,如果 ++、-- 在前,则先自加或自减,再代入运算。
在参与运算时,如果 ++、-- 在后,则先代入原值运算,再进行自加或自减。
表达式的结果为参与运算的数值中类型最大的数据类型。
计算得出的结果本身没有数据类型
参与计算的数据的类型中,在内存中被分配空间最大的数据类型决定了计算结果的数据类型。
如:int i = 10/3; 的结果为 3,因为参与计算的数据的类型都是 int
(2)关系运算符
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于
引用数据类型需要使用 equals() 方法比较否相同,如果使用 == 则比较数据空间的地址
(3)布尔逻辑运算符
与 & && 如果有两个条件,两个都为真时,结果为真
或 | || 如果有两个条件,有一个为真时,结果为真
非 ! 非真即为假,非家即为真
逻辑与 &: 无论是否有条件位 false 都判断完所有的条件
短路与 && :当从左到右有条件为 false 时,不再往下判断
逻辑或 |: 无论是否有条件位 true 都判断完所有的条件
短路或 ||: 当从左到右有条件为 true 时,不再往下判断
(4)位运算符
~ 取反
& 按位与
| 按位或
^ 按位异或
>> 右移
<< 左移
>>> 无符号右移按位与
计算机在保存数字的过程中保存的是数的补码:
- 正数的补码是其本身
- 负数的补码取反+1
byte a = 127;
a = (byte)(a + 1);
//结果:-128
- 取反 ~
计算机中正数从 0 开始
负数从 -1 开始
0 取反得到 -1
int a = ~20;
a = -21
~a = -(a+1)
- 按位与 &、按位或 |
//按位与 &,两个数都为 1 时才为 1
1001 0010
0100 1011
结果: 0000 0010
//按位与 &,两个数都为 0 时才为 0
1001 0010
0100 1011
结果: 1101 1011
- 异或 ^
0100 1011
结果: 1011 0100
任何数和 0 异或等于本身
任何数与本身异或等于 0
//用异或将两个数值的位置调换
a=a^b;
b=a^b; -> b=a^b^b; -> b=a;
a=a^b; -> a=a^b^a; -> a=b;
- 位移 <<、>>、>>>
左移 相当于乘 2
右移 相当于除 2。正数补 0 负数补 1
无符号右移。正数和负数都补 0
(5)三目运算符
//语法
条件 ? 真 : 假;
“真”和“假”处返回值的数据类型必须相同;
//简单运用
String a = age > 18 ? "成年" : "未成年";
//嵌套运用
String b = age < 18 ? "未成年" : age < 40 ? "青年" :age < 65 ? "中年" : "老年";
(6)赋值运算符
= 赋值
+= 先进行加法运算或字符串拼接后再赋值
-= 先进行减法运算再赋值
*= 先进行乘法运算再赋值
/= 先进行除法运算再赋值
%= 先进行取余运算再赋值
&= 先进行按位与运算再赋值
|= 先进行按位或运算再赋值
^= 先进行取反运算再赋值
<<= 先进行左移运算再赋值
>>= 先进行右移运算再赋值
>>>= 先进行无符号右移运算再赋值
- 两种会报错的情况
byte n = 127;
n = n + 1; 报错 - 编译失败
n += 1; 不报错
n += 1; 不会改变变量本身的数据类型。
n = n + 1;编译失败,因为1默认是int,运算的结果 n 成了 int 类型。
变量会报错
byte a = 1;
byte b = a + 1;
数字不会报错
byte b = 1 + 1;
具体的数字可以被程序获取,在数值不超过数据类型的最大值是,数字的数据类型与等号左边定义的数据类型相同
因为变量的数值的不确定性,所以程序会默认取“参与计算的具体数值”中的最大数据类型。
(7)运算符优先级
&& 的优先级大于 ||
由先到后:
()
!、~、++、–
*、/、%
+、-
<<、>>、>>>
<、<=、>、>=
==、!=
&
^
I
&&
||
?:
=