达内金牌讲师唐亮Java语言细节(下)

2016-02-19 20:10 12 1 收藏

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的达内金牌讲师唐亮Java语言细节(下)教程,一起来看看吧!超容易上手~

【 tulaoshi.com - 编程语言 】

8,拓宽数值类型会造成精度丢失吗?
  Java语言的8种基本数据类型中7种都可以看作是数值类型,我们知道对于数值类型的转换有一个规律:从窄范围转化成宽范围能够自动类型转换,反之则必须强制转换。请看下图:P=I85C
  byte--short--int--long--float--double%
  char--int"G
  我们把顺箭头方向的转化叫做拓宽类型,逆箭头方向的转化叫做窄化类型。一般我们认为因为顺箭头方向的转化不会有数据和精度的丢失,所以Java语言答应自动转化,而逆箭头方向的转化可能会造成数据和精度的丢失,所以Java语言要求程序员在程序中明确这种转化,也就是强制转换。那么拓宽类型就一定不会造成数据和精度丢失吗?请看下面代码:hc/N@
  int i=2000000000;n
  int num=0;?H=
  for(float f=i;f   num++;.}Q}1
  }©达内IT技术论坛—中国人学Java、学C++、学C#/.Net、学软件、学IT的地方 -- 达内科技论坛  ^n{P]W
  System.out.println(num);=u
  请考察以上代码输出多少?C/q+
  假如你回答50 ,那么请运行一下,结果会让你大吃一惊!没错,输出结果是0,难道这个循环根本就没有执行哪怕一次?确实如此,假如你还不死心,我带你你看一个更诧异的现象,运行以下代码,看输出什么?~
  int i=2000000000;9
  float f1=i;yW
  float f2=i+50;g
  System.out.println(f1==f2);d
  哈哈,你快要不相信你的眼睛了,结果竟然是true;难道f1和f2是相等的吗?是的,就是这样,这也就能解释为什么上一段代码输出的结果是0,而不是50了。那为什么会这样呢?要害原因在于你将int值自动提升为float时发生了数据精度的丢失,i的初始值是2000000000,这个值非常接近Integer.MAX_value,因此需要用31位来精确表示,而float只能提供24位数据的精度(另外8位是存储位权,见IEEE745浮点数存储规则)。所以在这种自动转化的过程中,系统会将31位数据的前24位保留下来,而舍弃掉最右边的7位,所以不管是2000000000还是2000000050,舍弃掉最右边7位后得到的值是一样的。这就是为什么f1==f2的原因了。IwY'q
  类似的这种数值拓宽类型的过程中会造成精度丢失的还有两种情况,那就是long转化成float和long转化成double,所以在使用的时候一定要小心。
  
  9,i=i+1和i+=1完全等价吗?
  可能有很多程序员认为i+=1只是i=i+1的简写方式,其实不然,它们一个使用简单赋值运算,一个使用复合赋值运算,而简单赋值运算和复合赋值运算的最大差别就在于:复合赋值运算符会自动地将运算结果转型为其左操作数的类型。看看以下的两种写法,你就知道它们的差别在哪儿了:1wa
  (1) byte i=5;Zvt^o
  i+=1;`d.
  (2) byte i=5;F1p
  i=i+1;J&
  第一种写法编译没问题,而第二种写法却编译通不过。原因就在于,当使用复合赋值运算符进行操作时,即使右边算出的结果是int类型,系统也会将其值转化为左边的byte类型,而使用简单赋值运算时没有这样的优待,系统会认为将i+1的值赋给i是将int类型赋给byte,所以要求强制转换。理解了这一点后,我们再来看一个例子:@4DiYK
  byte b=120;e-
  b+=20;6(dTP
  System.out.println("b="+b);+e6_+
  说到这里你应该明白了,上例中输出b的值不是140,而是-116。因为120+20的值已经超出了一个byte表示的范围,而当我们使用复合赋值运算时系统会自动作类型的转化,将140强转成byte,所以得到是-116。由此可见,在使用复合赋值运算符时还得小心,因为这种类型转换是在不知不觉中进行的,所以得到的结果就有可能和你的预想不一样。

来源:http://www.tulaoshi.com/n/20160219/1622908.html

延伸阅读
发展宝宝语言能力的对话游戏 0~1岁“对话”,建立牢固的亲子关系 宝宝出生时的第一声啼哭,就是他来到这个世界说出的第一句话!之后,宝宝的每一次啼哭,细心的妈妈都能知道他所“说的话”是什么意思:饿了,尿湿了,还是希望妈妈抱抱?母子间的“对话”就这样开始了。通过不断地“对话”...
第八章 Java的“异常”                      “ 异 常” 指 的 是 程 序 运 行 时 出 现 的 非 正 常 情 况。 在 用 传统 的 语 言 编 程 时, 程 序 员 只 能 通 过 函 数 的 返 回 值 来 发 出错 误 信 息。 这 易 于 导 致...
五、 面向对象篇 34 extends和implements有什么不同? 答:extends用于(单)继续一个类(class),而implements用于实现一个接口(interface)。 interface的引入是为了部分地提供多继续的功能。在interface中只需声明方法头,而将方法体留给实现的class来做。这些实现的class的实例完全可以当作interface的实...
包装器实现 包装器实现是一种将它们的实际工作委托给一个特定 对象集 的实现,它在该 对象集 所提供的功能之上又增加了额外的功能。 对design patterns(设计样式) 爱好者来说,这是一个 decorator(油漆工) 样式。虽然有点异国情调,但确实简单明了。 !-- frame contents -- !-- /frame contents -- ...
预告:网易学院近期即将独家推出Java入门系列原创连载教程,敬请期待 Java的盛宴(上)·Java的盛宴(中)·Java的盛宴(下) 曾几何时,国外的Java图书出现过三大系列鼎足而立的态势。这就是Pearson集团旗下的Prentice Hall和Addison Wesley与Sun公司合作推出的Sun Press Java系列,Wrox公司的Java系列和O'Reilly公司的Java...

经验教程

905

收藏

41
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部