在Java中,有算术运算符、关系运算符、逻辑运算符、位运算符、下标运算符、成员运算符、赋值运算符等。
运算符有三个特性:
1) 运算量个数。例如:加法运算,需要两个运算量。那么加法运算符就是二元运算符;正号运算符,只需要一个运算量,那么它就是一元运算符。
2)结合性。复合表达式中,运算顺序分别从左到右,和从右到左两种。例如,a+b+c;首先运算a+b的和,再与c相加。它的结合性是从左到右,即左结合性。
3) 优先级。复合表达式中,运算符的运算顺序不只受结合性的影响,还要受优先级的影响。例如,a+b*c;首先运算b*c的积,再求a加b*c的积。那么,乘法运算符的优先级高于加法运算符。
算数运算符
算数运算符包括+、-、*、/、%、++、--。算数运算符的运算量只能是数值类型或运算结果为数值类型的表达式(+可以应用于String类型)。算数表达式的运算结果为数值类型。
注意当参与/运算的两个操作数都是整数时表示整数除法,否则表示浮点除法。整数求余用%表示。整数被0除将会产生一个异常,而浮点数被0除会得到无穷大或NAN。
逻辑运算符
逻辑运算符包括!(逻辑非)、&&(逻辑与)、||(逻辑或)。运算量必须是boolean型或运算结果为boolean型的表达式。逻辑表达式的值也是boolean型。
&&和||是按照“短路”方式求值的。如果第一个运算量已经能够确定值,第二个运算量就不必计算了。例如,a&&b,如果a为false,那么结果不可能为true。因此b的值就没有必要计算了。与之类似,对于a||b,当a为true时,结果不可能为false,那么不必再计算b的值。这就是短路方式。
Java还给出了非短路方式的逻辑与(&)、逻辑或(|)。例如a&b,无论a的值是否能够确定表示式的结果,都会继续计算b的值。
关系运算符
关系运算符包括>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、==(恒等于)、!=(不等于)六种。前四种的运算量只能是数值类型,后两种的运算量可以是数值及引用类型。关系运算符的运算结果为boolean类型。前四种的优先级大于后两种。
位运算符
位运算是按照二进制位进行运算的。它包括&(按位与)、|(按位或)、^(按位异或)、~(按位非,即取反)、<<(左移)、>>(有符号右移或算术右移)、>>>(无符号右移或逻辑右移)。位运算符的运算量必须是整型,其结果也是整型的。
0000 0111
& 0000 0011
-------------
0000 0011
&,相同位的两个数值进行运算,如果两个数都为1那么该运算结果为1,否则为0。
0000 0111
| 0000 0011
-------------
0000 0111
|,相同位的两个数值进行运算,如果两个数都为0,该位运算结果0,否则为1。
0000 0111
^ 0000 0011
-------------
0000 0100
^,相同位的两个数值进行运算,如果两个数相同,该位运算结果0,否则为1。
0000 0111
-------------
1111 1000
~,将每一位上的数值取反,1取反为0,0取反为1。
0000 0111
<< 1
-------------
0000 1110
<<,将所有位向左移动1位,进位溢出,空位补0。
0000 0111
>>> 1
-------------
0000 0011
>>>,将所有位向右移动1位,进位溢出,空位补0。
0000 0111
>> 1
-------------
0000 0011
>>,将所有位向右移动1位,进位溢出,空位补“符号值”。
赋值运算符
赋值运算符包括=。赋值运算符的运算量可以是任意类型,结果根据运算量而定。
复合赋值运算符包括+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=。它们把其它运算与赋值运算融合到一起,形成了复合赋值运算符。
复合运算符中隐含了强制转换,效率较高。
赋值变量未初始化,会报错。
条件运算符
条件运算符只有一个?:,它是Java中唯一一个三元运算符。a?b:c,a运算量必须是boolean类型,而其它两个运算量可以是任意类型。表达式的结果取决于a是true还是false,如果a为true,那么表达式的值为b(即冒号左边的),否则为c(即冒号右边的)。char c=b?'男':'女';
运算符优先级和结合性
优先级 | 运算符 | 名称 | 结合性 | 运算量 |
1 | () | 括号 | 无 | 无 |
1 | . | 成员运算符 | 从左到右 | 一元 |
1 | () | 方法调用运算符 | 从左到右 | 一元 |
1 | [] | 下标运算符 | 从左到右 | 一元 |
2 | ! | 逻辑非运算符 | 从右到左 | 一元 |
2 | ~ | 取反运算符 | 从右到左 | 一元 |
2 | ++、-- | 自增、自减运算符 | 从右到左 | 一元 |
2 | +、- | 正号、负号运算符 | 从右到左 | 一元 |
2 | () | 强制类型转换运算符 | 从右到左 | 一元 |
2 | new | 新建运算符 | 从右到左 | 一元 |
3 | *、/、% | 乘、除、取余运算符 | 从左到右 | 二元 |
4 | +、- | 加法、减法运算符 | 从左到右 | 二元 |
5 | <<、>>、>>> | 左移、算术右移、逻辑右移 | 从左到右 | 二元 |
6 | <、<=、>、>= | 小于、小于等于、大于、大于等于 | 从左到右 | 二元 |
6 | instanceof | 实例运算符 | 从左到右 | 二元 |
7 | ==、!= | 恒等于、不等于 | 从左到右 | 二元 |
8 | & | 按位与 | 从左到右 | 二元 |
9 | ^ | 按位异或 | 从左到右 | 二元 |
10 | | | 按位或 | 从左到右 | 二元 |
11 | &&(&) | 逻辑与 | 从左到右 | 二元 |
12 | ||(|) | 逻辑或 | 从左到右 | 二元 |
13 | ?: | 条件运算符 | 从右到左 | 三元 |
14 | =、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、 >>>= | 赋值及复合赋值运算符 | 从右到左 | 二元 |
类型转换
数值类型之间的合法转换
实箭头表示的转换为无数据丢失的转换,虚箭头表示的转换过程中可能会损失精度。
当两个数值进行运算时,先要将运算量转换为同种类型再计算。
如果两个运算量中有一个是double类型的,那么另一个运算量将会转换为double类型。
否则,如果其中一个运算量是float类型,那么另一个运算量将会转换为float类型。
否则,如果其中一个运算量是long类型,那么另一个运算量将会转换为long类型。
否则,两个运算量都将被转换为int类型。
强制类型转换
int类型的值将会自动地转换为double类型。但另一方面,有时也需要将double转换成int。在Java中,允许进行这种数值之间的类型转换,当然,有可能会丢失一些精度。在这种情况下,需要通过强制类型转换实现这个操作。
double n=9.9997; int x=(int)n;//x=9;
double n=9.9997; int x=(int)Math.round(n);//x=10;