读《java编程思想》3-操作符

1、赋值
基本类型赋值:左边必须有一个物理空间 可以存储右边的值。如a = 1
对象赋值:将一个引用指向一个对象。如b = "string"
对象引用赋值:复制一个引用,两个引用指向同一个对象。如c = b
 
2、算数运算符
(1)优先级:先一元后多元,先乘除后加减,最后赋值。(最常见)
(2)算数运算符和赋值组合使用,如+=,-=
(3)Random 构造函数参数是种子,不传默认当前时间,如果指定种子,则每次产生的随机数相同。(伪随机)
(4)自动递增 和 递减 ++ --
前缀式 先运算后赋值
后缀式 先赋值后运算
(java=c++--)
 
3、关系操作符
(1)基本数据类型使用== != 比较值是否相同,而对象则是比较引用的是否为同一个对象。
(2)对象使用equals比较值,需要复写equals方法,默认实现是==(比较引用)。如:基本数据类型和string可以直接通过equals比较值,也是因为已经复写equals方法。
(3)包装类型和 基本数据类型比较时,先解包。
 
4、逻辑运算符
(1)&& || ! 只能用于布尔值。
(2)会发生短路:一旦能够确定整个表达式的值,就不会再计算表达式余下部分。
(3)直接常量,编译器通过值可以准确知道数据类型。
Int: 0x 0X 十六进制,0八精致 (数字零),如 0x12,023
long: l L,如 123123123123Ll,long对象赋值时,当值超过int范围时,必须加后缀l。
float: f F,如123.0f ,float赋值时,当值带小数点时必须加后缀f。
double: d D,如123123123123.0d,double赋值时,可以不加后缀。
(4)Integer.toBinaryString、Long.toBinaryString 十进制转二进制 (更多转换方法见扩展1)
(5)指数计数法
e表示0, 1e2 即 100
 
5、按位操作符
(1)|、&、^、~
按位与 a&b 都为1结果为1,否则为0
按位或a|b 都为0结果为0,否则为1
异或a^b 相同为0,不同为1
非~a 取反
(2)不会发生短路
(3)&=、|=、^= 合法,~= 不行
(4)boolean 值 可以按位操作(除了~)
 
6、移位运算符
(1)只能处理整数类型
(2)java中使用补码运算。(原因见扩展2)
(3)<<、>>、>>>
<<左移 低位补0;>>右移 高位符号扩展,正数补0,负数补1;>>>无符号右移,高位补0
(4)a>>>=b 操作位数的低5位有效 (原因见扩展3)
(5)num << n 相当于 num * 2的n次方,
num >> n 相当于 num / 2的n次方。
(6)byte、char、short 无符号右移时, 如果和赋值运算符结合使用,可能会得到错误的结果。(原因见扩展4)
 
7、三元操作符 x > y ? a : b
引入为了减少代码行数,高效编程,但是频繁使用,降低代码可读性。
 
8、类型转换
(1)类型转换 很像但不是移位操作(6)
窄化转换,如 long(64位)转化为 int (32位),会丢失高位32位数。因此需要强制类型转换。 int a = (int) b;
扩展转换,如 int(32位)转化为long(32位),正数高位补32个0,负数补32个1,数值不变(注意是补码),因此不需要强制转换。
(2)基本数据之间可以自由转换(包括强制),boolean 除外。
 
9、类型提升
(1)比int小的类型(byte,char, short)进行运算时先转换为int,所以结果也是int。如果要转换回short 需要强制转换。
short a = 1;
short b = 2;
short c = (short)(a + b);
(2)运算表达式中最大的数据类型决定结果的数据类型。
 
10、java没有sizeof
java中数据类型大小确定,不会因为运行环境不同而改变,所以没有sizeof。
 
11、扩展
(1)数制转换(Integer 和 Long 方法相同)
十进制转成十六进制:
Integer.toHexString(int i)
十进制转成八进制
Integer.toOctalString(int i)
十进制转成二进制
Integer.toBinaryString(int i)
十六进制转成十进制
Integer.valueOf("FFFF",16).toString()
八进制转成十进制
Integer.valueOf("876",8).toString()
二进制转十进制
Integer.valueOf("0101",2).toString()
直接将2,8,16进制直接转换为10进制
java.lang.Integer类
parseInt(String s, int radix)
 
(2)为什么计算机使用补码运算
比如计算 7 + (-6),转换二进制计算,(答案应该是1)
如果使用源码0 000 0111 + 0 000 0111 = 1 000 1100 (结果负数错误);
如果使用反码0 000 0111 + 1 111 1001 = 1 0 000 0000 高位溢出后为 0 0 00 0000 (答案0错误)
如果使用补码0 000 0111 + 1 111 1010 = 1 0 000 0001 高位溢出后为 0 0 00 0001 (答案1正确!)
另外 +0 和 -0 在补码中都是 0 000 0000,那么 剩下的1 000 0000,在无符号中可以多表示一个数即128。
 
(3)a>>>=b 其中b的有效位数
如果a是int类型,则b最大为32,即,b转换为二进制,低5位有效;如果a是long类型,则b最大为64,即,b转换为二进制,低6位有效。
如 100 >> 99 、100 >> 35 、100 >> 3 的值都是12。
99 转二进制 1100011,截取后5位 11
35 转二进制 100011 ,截取后5位 11
3 转二进制 11
 
(4)byte、char、short 无符号右移后,可以赋值给int,但不要再赋值给原来的类型,可能会造成结果错误。
//情况1
short i = -1;
i >>>= 10; //先转int 变为32个1(负数),向右移位10位,高位补0,则是10个0和22个1(变成了正数),然后赋值给short,则截断保留低位16个1(负数)
System.out.println(Integer.toBinaryString(i)); //toBinaryString参数为int,这里由short转为int ,负数高位补1,则变为32个1
 
//情况2
short s = -1;
System.out.println(Integer.toBinaryString(s >>> 10)); //没有赋值给原来的short
 
输出:
11111111111111111111111111111111 (结果-1 错误!)
1111111111111111111111
(即00000000001111111111111111111111 结果4194303 正确)
 
 
参考
《java编程思想第四版》
https://blog.csdn.net/gloness/article/details/79722430
 
 
 

猜你喜欢

转载自www.cnblogs.com/shineup/p/11453183.html
今日推荐