------- android培训、java培训、期待与您交流! ----------
在申请进入黑马程序员考试的时候,碰到一个题,引发了我一系列对java运算符的思考。
一、题目:
1、以下代码哪个是正确的?为什么?
a. byte b = 1 + 1;
b. byte b = 1; b = b + 1;
c. byte b = 1; b = b += 1;
d. byte b = 1; b = ++b;
答案是很明确的,大家都知道是a,c,d,但是仅仅知道答案是不行的,我们要知其然,亦要知其所以然。经过多番学习,终于有了一些自己的见解,现在分享给大家,错误之处,大家多多指正。
二、题目分析
对于a选项中的数据,运算过程是这样的,编译时期,虚拟机会判断“=”的值是否在byte的取值范围之内,如果是在范围之内,则可以通过编译,byte的取值范围是-128~127,因此可以通过编译;a正确
对于b选项,看起来跟a一样,但是“=”号右边的值中有变量,变量就会存在不确定的因素,在编译时期无法确定值,就存在安全隐患,因此无法通过编译;故b错误
对于c选项,其实b += 1等价于b = (byte)(b +1);因此就不会报错了
对于d选项,++在自身的基础上加1,也就可以通过了
三、让人纠结的运算符
按照功能划分运算符可分为七类,我主要分享的是算数术运算符(++),布尔逻辑运算符(&&与&的区别,赋值类运算符 (+=)的看法,运算符看起来是很简单的事情,但是事情却并非如此。
(1)算数术运算符--自增
初学编程语言的时候,大家对++肯定相当不解,老师会告诉你,int a = 3; (a++) * 3 = 9,而 (++a) * 3 = 12,这是为什么呢?
那么我们来看一看前++与后++的区别,
++a表示取a的地址,增加它的内容,然后把值放在寄存器中;a++ 则表示取x地址,把它的值装入寄存器中,然后增加内存中x的值。
所以计算的时候,我们用寄存器中的值来计算,这样,问题就迎刃而解了。
(2)逻辑运算符(&&与&的区别)
区别:&&运算符在计算的时候,若左边的数值为false,那么直接判断值为false,而&仍会判断右边的值,然后再判断出结果
&运算符同时也是位运算符
(3)赋值类运算符(+=)中的陷阱
byte b = 1; b += 1;等价于byte b = 1; b = (byte)(b + 1);
这里的隐式转换就是陷阱的关键,若b = 127时,b + 1 = 128,但是通过+=运算符运算出来的却是-128,其实这中间就出现了高位遗失,丢失精度,
因此大家一定要小心。尤其在下面三种情况下:
1)将复合赋值运算符用于byte,short,char等类型的变量
2)将复合赋值运算符用于int类型的变量,而右侧表达式则是long,float,double类型的值,如
int b = 2;
b += 2.2;
3)将复合赋值运算符用于float类型的变量,而右侧表达式则是double类型的值,如
float f = 2.2f;
b += 2.3;