3.5 运算符
3.5.1 自增运算符与自减运算符
在Java中,借鉴了C/C++的实现方式,也使用了自增,自减运算符:n++将变量n的当前值加1;n--将n的值减1.3.5.2 关系运算符与 boolean 运算符
Java沿用了C++的习惯,用&&表示逻辑"与",用||表示逻辑"或". &&和||是按照"短路"方式求值的.如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了.如果&&对两个表达式进行计算:expression1 && expression;
并且第一个表达式值为 false,结果不可能为真.因此,第二个表达式的值就没有必要计算了.这种方式可以避免一些错误的发生.例如,表达式:
x != 0 && 1 / x > x + y // no division by 0
当 x 为 0 时,不会计算第二部分.
因此,若 x 为 0, 1/x不被计算,也不会出现除以 0 的错误.
与之类似,对于expression1 || expression2,当第一个表达式为 true 时,结果自动为 true,不再计算第二部分.
最后,Java支持三元操作符?:,在许多时候,这个操作符很有用.表达式:
condition ? expression1 : expression2;
当条件condition为真时,计算第1个表达式,否则计算第2个表达式.例如:
x < y ? x : y
返回 x 和 y 中较小的那个值.
3.5.3 位运算符
在处理整型数值时,可以直接对组成整型数值的各个位进行操作.这意味着 可以使用屏蔽技术获得整数中的各个位.位运算符包括:&("与"),|("或"),^("异或"),~("非")
这些运算符在位模式下工作.例如,如果n是一个整型变量,并且用二进制表示的n从右数第4位为1,那么:
int fourthBitFromRight = (n & 0b1000) / 0b1000;
返回1,否则返回0.通过运用2的幂次方的&运算可以将其他位屏蔽掉,而只保留其中的某一位.
另外,">>"和"<<"运算符将二进制位进行右移或左移操作.当需要建立位模式屏蔽某些位时,使用这两个运算符十分方便:
int fourthBitFromRight = (n & (1 << 3)) >> 3;
最后,>>>运算符将用0填充高位,<<运算符用符号位填充高位.没有<<<运算符.
注释:在C/C++中无法确定>>操作执行的是算术移位(扩展符号位),还是逻辑移位(高位添0).在执行中将会选择效率较高的一种.这就是说,在C/C++中,>>运算符实际上只是为非负数定义的.Java消除了这种含糊性.
3.5.4 数学函数与常量
在MAth类中,包含了各种各样的数学函数.在编写不同类别的程序时,可能需要的函数也不同.想要计算一个数值的平方根,可以使用sqrt方法:double x = 4;
double y = Math.sqrt(x);
System.out.println(y); // prints 2.0
注释:println方法和sqrt方法存在微小的差异.println方法操作一个定义在System类中的System.out对象.但是,MAth类中的sqrt方法处理的不是对象,这样的方法被称为静态方法.
在Java中,没有幂运算,因此需要借助于MAth类中pow方法.语句:
double y = Math.pow(x, a);
将 y 的值设置为 x 的 a 次幂.pow方法有两个 double 类型的参数,其返回结果也为 double 类型.
Java还提供了两个用于表示Π和e常量的近似值:
Math.PI
Math.E
提示:不必在数学方法名和常量名前添加前缀"MAth.",只要在源文件的顶部加上下面这行代码就可以:
import static java.lang.Math.*;
例如:
System.out.println("The square root of \u03c0 is " + sqrt(PI);
3.5.5 数值类型之间的转换
3.5.6 强制类型转换
强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名.例如:double x = 9.97;
int nx = (int)x;
这样,变量 nx 的值为9.强制类型转换通过截断小数部分将浮点值转换为整型.
如果想要对浮点数进行舍入运算,以便得到最接近的整数,那就需要使用Math.round方法:
double x = 9.97;
int nx = (int)Math.round(x);
现在,变量 nx 的值为10.当调用round时,仍然需要使用强制类型转换(int).其原因是round方法返回的结果为 long 类型,由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能够将 long 类型转换为 int 类型.
注释:只有极少数情况才需要将 boolean 类型转换为数值类型,这是使用条件表达式 b ? 1 : 0 .
3.5.7 括号与运算符级别
运算符优先级
运算符 结合性
[].()(方法调用) 从左向右
! ~ ++ -- +(一元运算) -(一元运算) ()(强制类型转换) new 从右向左
*/% 从左向右
+ - 从左向右
<< >> >>> 从左向右
< <= > >= instanceof 从左向右
== != 从左向右
& 从左向右
^ 从左向右
| 从左向右
&& 从左向右
|| 从左向右
?: 从右向左
= += -= *= /= %= &= |= ^= <<= >>= >>>= 从右向左
3.5.8 枚举类型
有时候,变量的取值只在一个有限的集合内.可以自定义枚举类型.枚举类型包括有限个命名的值.例如:
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE};
现在,可以声明这种类型的变量:
Size s = Size.MEDIUM;
Size类型的变量只能存储这个类型声明中给定的某个枚举值,或者null值,null表示这个变量没有设置任何值.