经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Java开发笔记(七)强制类型转换的风险
来源:cnblogs  作者:pinlantu  时间:2018/10/8 9:19:33  对本文有异议

编码过程中,不但能将数字赋值给某个变量,还能将一个变量赋值给另一个变量。比如下面代码把整型变量changjiang赋值给整型变量longRiver:

  1. // 长江的长度为6397千米
  2. int changjiang = 6397;
  3. System.out.println("changjiang="+changjiang);
  4. int longRiver = changjiang; // 把一个整型变量赋值给另一个整型变量
  5. System.out.println("longRiver="+longRiver);

 

运行上面的测试代码,发现两个整型变量的数值一模一样。

同类型的变量之间互相赋值完全没有问题,麻烦的是给不同类型的变量赋值。要是把整型变量赋值给长整型变量,则发现编译器直接提示错误,此时需要在原变量前面添加“(新类型)”表示强制转换类型。改写后的变量赋值语句就变成了下面这样:

  1. // 不同类型的变量相互赋值,需要在原变量前面添加“(新类型)”表示强制转换类型
  2. long longRiver = (long) changjiang; // 把整型变量赋值给长整型变量

 

然而,不同类型的变量相互赋值是有风险的,尤其是把高精度的数字赋值给低精度的数字,例如将八字节的长整型数强制转成四字节的整型数,结果只有低位的四个字节保留了下来,而高位的四个字节被舍弃掉了。下面做个实验,先用长整型变量保存世界人口的数量74亿,再把该长整型变量赋值给整型变量,具体代码如下所示:

  1. // 截至2018年元旦,世界人口大约有74亿
  2. long worldPopulation = 7444443881L;
  3. System.out.println("worldPopulation="+worldPopulation);
  4. // 把长整型数赋值给整型数会丢失前四个字节
  5. int shijierenkou = (int) worldPopulation; // 把长整型数强制转成整型数
  6. System.out.println("shijierenkou="+shijierenkou);

 

运行以上的实验代码,打印出来的变量值见以下日志:

  1. worldPopulation=7444443881
  2. shijierenkou=-1145490711

 

可见长整型数强制转成整型数,结果整个数值都变掉了。

既然整数之间强制转换类型存在问题,小数之间的类型强制转换也不例外。倘若把双精度数强制转换成浮点数,数字精度也会变差。接下来仍然通过实验进行观察,以常见的圆周率为例,它的密率是中国古代数学家祖冲之发现的,其数值为3.1415926,包括小数部分在内共有8位数字。由于double类型的数字精度达到15到16位,因此利用双精度变量保存圆周密率完全没有问题。但是如果将这个密率的双精度变量赋值给浮点变量,又会发生什么情况?下面的代码就演示了把双精度数强制转成浮点数的场景:

  1. // 3.1415926是中国古代数学家祖冲之求得的圆周率数值,又称祖率
  2. double zulv = 3.1415926;
  3. System.out.println("zulv="+zulv);
  4. // 把双精度数赋值给浮点数会丢失数值精度
  5. float pai = (float) zulv; // 把双精度数强制转成浮点数
  6. System.out.println("pai="+pai);

 

运行上述实验代码,日志打印的变量值见下:

  1. zulv=3.1415926
  2. pai=3.1415925

 

可见浮点变量保存的密率数值变成了3.1415925,与双精度变量相比,末尾的6变为5。之所以密率数值发生变化,是因为float类型的数字精度只有6到7位,而前述密率的总位数达到8位,显然超出了float类型的精度范围,使得强转之后的浮点变量损失了范围外的精度。

除了整数之间互转、小数之间互转以外,还有整数转小数和小数转整数的情况,可是整数与小数互转依然存在数值亏损的问题。譬如一个双精度变量赋值给一个整型变量,由于整型变量没有空间保存小数部分,因此原本双精度变量在小数点后面的数字全被舍弃。以下代码就示范了这种数字类型转换的例子:

  1. double jiage = 9.9;
  2. System.out.println("jiage="+jiage);
  3. // 把小数赋值给整型变量,会直接去掉小数点后面部分,不会四舍五入
  4. int price = (int) jiage; // 把双精度数强制转成整型数
  5. System.out.println("price="+price);

 

运行以上的测试代码,日志打印结果如下:

  1. jiage=9.9
  2. price=9

 

果然整型变量丢掉了双精度变量的小数部分,由此可见,不同类型之间的变量互转问题多多,若非必要,一般不进行两个变量的类型强制转换操作。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号