我们知道,在Java以及很多高级编程语言当中,都有一种运算符叫做复合赋值运算符。复合赋值运算符由两个符号组成,它所能完成的运算操作也分为两步:第一步是运算,第二步是赋值。比如说:
上面的这两条语句相当于
但是,如果碰到下面这样的情况,a的值该应该是多少呢?
有人认为应该按以下方式来计算,因为我们都知道,在四则运算规则中,遵循“先乘除,后加减”的原则
按照这样的方式来计算,得到a的值应该是7,但实际运行程序所得到的结果是8。这是为什么呢?
就是因为复合赋值运算符在完成运算的时候,遵循一个规则:把“=”右边当作整体!也就是说,刚才的运算和赋值操作应该被解释为以下形式
因此,按照这种方式,“=”右边的“3+1”应该被当作整体,优先进行运算,所以得到的最终计算结果就是变量a的值为8。
我们再来看另外一个问题,这一次,我们把变量a的类型由原来的int改为short。
我们这么写代码没有任何问题,能够顺利通过编译。但是,如果我们没有使用复合赋值运算符,而是按如下所示的方式编写代码
在这种情况下,大家可以看到代码不能通过编译。我们把一个算术表达式的运算结果赋值给byte或者是short类型的变量,有时候会引起编译错误,所以按这种方式写代码会导致编译错误。关于引起这种错误的原因,大家可以看我的另一篇文章《Java千问05:Java语言中为byte和short类型变量赋值为啥会报错?》,该文对此现象有详细解释。我们现在重点讨论使用复合赋值运算符进行操作的时候,同样会有给short类型变量赋值的操作,为什么就不报错呢?原因就是:使用复合赋值运算符在对变量进行赋值的时候,编译器会“暗地里”加上一个强制类型转换的操作。也就是说,使用复合赋值运算符进行操作的时候,实际上等同于如下写法
这种强制类型转换,其实有可能让我们的程序在不经意间产生莫名其妙的错误,请看下面的例子
这一次,我们把a的初始值由原来的2改成了20000,并且在代码中还加入了输出a的语句,那么,输出结果会是多少呢?首先来讲,这段代码并没有报错,那么这个输出结果会让人很多人大吃一惊,它并不是我们想象的80000,而是竟然输出了14464!
之所以会输出这样的结果,就是因为80000已经超出了short类型数据的最大值,而我们强制把这个已经超过最大值的“80000”经过强制类型转换赋值给short变量,就会产生“溢出”,最终导致实际赋给变量a的是一个错误的值!最可恶的是,因为是强制类型转换之后进行的赋值,所以编译器并不报错,从而导致很多人掉到坑里还不知道!
通过这个篇文章,大家可以看到:一个简单的复合赋值运算符竟然也“暗藏杀机”,我们平时编程一定要小心哦!