解释如下:
short s = 3;
s = s + 2;
编译失败原因:
如果一个整数没有赋给一个声明了数据类型的变量,这个整数在参加运算的默认类型就是int类型。
“2”这个整数的默认数据类型是int类型,当进行s+2运算时,s发生了数据自动提升,也就是自动类型转换。
即:s自动转换为与2相同的数据类型int类型,然后进行了加法运算,
两个int类型的数据相加后肯定还是一个int类型,最后赋给数据类型为short的s时,就发生了数据丢失。
相关知识:
Java在需要和允许的情况下,总是将变量向着更高精度类型的方向转换,这样不会引起数据丢失,这个过程叫做类型提升(类型自动提升)。
在没有进行强制装换的情况下,高位数的数据不能转换为低位数的数据,否则造成数据丢失。金字塔赋值顺序是不可逆转的!
s+=2;
编译通过的原因:
因为“+=”运算符在给s赋值时,自动完成了强制类型转换操作,
综上所述,不能简单的认为,s+=2;与s = s + 2;不是等价的。
当short s = 3;
s+=2;与s = (short)(s + 2); 结果是一样的。
s+=2;与s = s + 2; 执行过程不是一样的,前者通过,后者不能通过。
拓展:
long l = 3;
l = l + 2;
System.out.println("l="+l);
可以通过编译,此时:l = l + 2;与l+=2;执行结果是一样的。
short型数据的范围是-32768~32767,在您给的示例中short s = 3,变量s的取值是3,。因为s是变量,所以s可以取其它的值,比如s可以等于32767,那么此时s + 2 的值为32769,就超过了short的取值范围。s+2超过了short的数值范围,再赋给short型变量s当然是不被编译器所允许的。您看,s=3时没有超过short的数值范围,理论上是可以编译通过的;s=32767时,超过了short的数值范围,理论上就不能通过编译。在s = s + 2代码行前,s因为是变量,可以取不同的数值,有时候可以取3,有时候也可以取32767,那么s = s + 2就有时候编译可通过有时候编译不可通过。编译器在遇到这种情况时,只能让该代码行s = s + 2不通过啦!这是我对您“s=s+2为什么不能编译通过”的解答,希望您能理解。
第2个问题,“为什么s+=2可以编译通过”。首先我向您明确一点,代码行编译通过是没有问题的,但这不是说,s的结果就是理论计算意义上一定是正确的!您看下面的示例:
short s = 32767;
s += 2;
System.out.println(s);
编译器上的运行结果是-32767。理论计算意义上讲您觉得它的结果是不是应该是32769?所以说,代码行s += 2的运算结果不一定是对的,它只是单纯地可通过编译而已!所以,我的建议是,您只需要记住什么形式可编译通过什么形式不可编译通过,但真正运行的时候还是需要谨慎的!因为程序最终还是要运行成功才行的。
希望我的解答能给您一些帮助!如果有什么说的不对的地方,请批评指正,共同进步嘛!