陷阱6 稍纵即逝——长整数运算中存在的隐患
在使用Java进行程序设计时,当为一个long型变量赋值一个整数常量时,如果这个值超出了int型数据的取值范围,程序就会出现编译错误,但是有一种情况程序不会出错,就是将多个int型数据进行算术运算的结果赋值给long型变量,即使这个运算结果超出了int型数据的取值范围,程序也不会出现编译错误。
说明
一个int 型数据在内存中占4个字节的存储空间,其取值范围为-231~ 231−1,也就是-2 147 483 648~2 147 483 647范围内的整数。而一个long型数据在内存中则占8个字节的存储空间,其取值范围为-263~ 263−1,也就是在-9 223 372 036 854 775 808~9 223 372 036 854 775 807范围内的整数。
(1)出现编译错误。
示例:
long num = 2147483648 ; // 为long型变量num赋值
说明
上面示例为long型变量num赋值2147483648,由于2147483648超出了int型数据的取值范围,所以程序发生了编译错误,为了能够正确赋值,需要在数值2147483648后加小写字母 "l" 或大写字母 "L" ,这样该示例就不会出错了。
(2)能通过编译,但结果错误。
示例:
long num = 2147483647 * 10 ; // 将两个整数常量的乘积,赋值给long型变量num System. out. println (num) ; // 输出变量num的值
说明
上面示例输出long型变量num的值为-10,并不是我们期待的结果21 474 836 470,这是因为参加计算的两个整数并没有超出int型数据的取值范围,所以不会产生编译错误,结果错误是由于当这两个数进行乘积运算时,是以int型数据进行计算的,所以计算结果也应该是int类型,由于计算结果超出了int型数据的取值范围,所以程序发生了溢出,但是程序会保留这个溢出的结果,所以输出了-10。
(3)既能通过编译,又能保证结果正确。
示例:
long num = 2147483647L * 10 ; // 将两个整数常量的乘积,赋值给long型变量num System. out. println (num) ; // 输出变量num的值
说明
上面示例输出long型变量num的值为21 474 836 470,这正是我们所期待的正确结果,这是由于在参加计算两个整数中的第一个整数常量后添加了大写字母 "L" ,这表示要进行的运算是按长整数进行的,所以程序不会产生溢出,因此可以计算出正确的结果。