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

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

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

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

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

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

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

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

worldPopulation=7444443881
shijierenkou=-1145490711

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

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

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

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

zulv=3.1415926
pai=3.1415925

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

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

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

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

jiage=9.9
price=9

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

Java开发笔记(七)强制类型转换的风险的更多相关文章

  1. Java开发笔记(七十三)常见的程序异常

    一个程序开发出来之后,无论是用户还是程序员,都希望它稳定地运行,然而程序毕竟是人写的,人无完人哪能不犯点错误呢?就算事先考虑得天衣无缝,揣着一笔巨款跑去岛国买了栋抗震性能良好的海边别墅,谁料人算不如天 ...

  2. Java开发笔记(七十六)如何预防异常的产生

    每个程序员都希望自己的程序稳定运行,不要隔三岔五出什么差错,可是程序运行时冒出来的各种异常着实烦人,令人不胜其扰.虽然可以在代码中补上try/catch语句捕捉异常,但毕竟属于事后的补救措施.与其后知 ...

  3. Java开发笔记(三十四)字符串的赋值及类型转换

    不管是基本的char字符型,还是包装字符类型Character,它们的每个变量只能存放一个字符,无法满足对一串字符的加工.为了能够直接操作一连串的字符,Java设计了专门的字符串类型String,该类 ...

  4. Java开发笔记(七十五)异常的处理:扔出与捕捉

    前面介绍的几种异常(不包含错误),编码的时候没认真看还发现不了,直到程序运行到特定的代码跑不下去了,程序员才会恍然大悟:原来这里的代码逻辑有问题.像这些在运行的时候才暴露出来的异常,又被称作“运行时异 ...

  5. Java开发笔记(七十九)利用反射技术操作私有属性

    早在介绍多态的时候,曾经提到公鸡实例的性别属性可能被篡改为雌性,不过面向对象的三大特性包含了封装.继承和多态,只要把性别属性设置为private私有级别,也不提供setSex这样的性别修改方法,那么性 ...

  6. Java开发笔记(七十)Java8新增的几种泛型接口

    由于泛型存在某种不确定的类型,因此很少直接运用于拿来即用的泛型类,它更经常以泛型接口的面目出现.例如几种基本的容器类型Set.Map.List都被定义为接口interface,像HashSet.Tre ...

  7. Java开发笔记(七十一)容器工具Collections

    清单作为一组数据的有序队列,它在组织形式上与数组有着某些异曲同工之处,数组有专门的数组工具Arrays来进行加工操作,照理清单也应该配备对应的清单工具.当然容器这个大家族确实拥有自己的容器工具Coll ...

  8. Java开发笔记(七十二)Java8新增的流式处理

    通过前面几篇文章的学习,大家应能掌握几种容器类型的常见用法,对于简单的增删改和遍历操作,各容器实例都提供了相应的处理方法,对于实际开发中频繁使用的清单List,还能利用Arrays工具的asList方 ...

  9. Java开发笔记(七十四)内存溢出的两种错误

    前面介绍的几种异常,其实都存在这样那样的逻辑问题,属于程序员的编码手误.还有一大类系统错误,表面上看不出什么问题,但是程序仍然运行不下去,兹举二例说明.第一个例子且看下列的测试代码: // 测试内存溢 ...

  10. Java开发笔记(七十七)使用Optional规避空指针异常

    前面在介绍清单用法的时候,讲到了既能使用for循环遍历清单,也能通过stream流式加工清单.譬如从一个苹果清单中挑选出红苹果清单,采取for循环和流式处理都可以实现.下面是通过for循环挑出红苹果清 ...

随机推荐

  1. 30 ArcGIS 许可管理器常见问题(持续更新中……)

    一.[单机版] 1.1.ArcMap 1.2.ArcGIS Pro 错误一 ArcGIS Pro单机许可安装授权,在Configure Authorization界面报“This functional ...

  2. Python基础之面向对象思维解决游戏《天龙八部》

    一.程序设计思维: 以面向对象的思维设计<天龙八部>游戏技能,使得技能效果在增加或者减少时,游戏技能整体框架不改变,仅仅增加或者减少技能效果 二.思路流程图如下: 三.变成框架实现代码: ...

  3. 简单工厂模式demo

    1. 简单工厂模式 domain的接口 public interface Color{ public void display(); } red public Class Red implements ...

  4. 值得收藏!!javascript数组中多条对象去重方式,很实用!!!

    在数组中都是数字的时候很好去重,例如:var  arr=[1,2,2,2,3,4,5,4,5,3,6]:可以用两层for循环或者其他方式进行去重 我在这里也给出一个方法吧: Array.prototy ...

  5. [Swift]LeetCode290. 单词模式 | Word Pattern

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  6. VSphere虚拟化ESXi的安装及基本管理

    虚拟化和云计算技术正在快速的发展,新的概念.观点.产品不断涌现.服务器虚拟化技术受到了人们的高度重视,普遍相信虚拟化将成为数据中心的重要组成部分.vSphere是VMware公司推出的一套服务器虚拟化 ...

  7. Kubernetes 笔记 05 yaml 配置文件详解

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Hi,大家好, ...

  8. 知识扩展--if...else...与switch...case...的执行原理

    一.简述 编程语言中的条件分支结构有两种:if-else和switch-case,这两种条件分支之间可以相互转换,但是也存在一些区别,那么什么时候该用if-else,什么时候该用switch-case ...

  9. git入门笔记汇总——(廖雪峰博客git入门)

    本文内容是对廖雪峰老师Git教程做的笔记,外加一些自己的学习心得,还抱着学以致用的心态来实践一番 如有显示错误 请移步本人github:git教程小结 Git学习笔记 Git简介 安装Git 创建版本 ...

  10. Centos7中文乱码问题的解决

    刚安装centos7之后,语言默认不是中文,导致中文路径或中文文件在系统中显示为乱码,查了些资料解决了这个问题. 1 查看和安装中文库 [root@bogon ~]# echo $LANG zh_CN ...