黑马程序员技术交流社区

标题: 关于类型转换的问题 [打印本页]

作者: java陈辉    时间: 2013-12-5 22:50
标题: 关于类型转换的问题
本帖最后由 java陈辉 于 2013-12-6 22:44 编辑

short s = 3; s = s+2; s+=2,为什么s=s+2编译失败,s+=2编译成功,这里有点不解,请详细讲解。

作者: 依然    时间: 2013-12-5 23:30
1.s=s+2,提示错误是会损失精度
   s为short,2为int,结果为int赋值给short,从int变成short可能会产生损失精度。
2.s+=2 可以通过
  其实是两个步骤的缩写:
  先执行:s+2  ,short 与 int 相加,类型自动转换成int相加 ,结果是5
  再执行:s = 5 , 操作,所以这个部分可以通过编译
作者: 然后呢    时间: 2013-12-5 23:47
s+=2实际上有强制转换的功能
作者: 纷飞尽    时间: 2013-12-6 00:48
java的自动转型是从小到大,而s=s+2这一步中,2是一个int型的数,不会自动转成short类型的,而后者却会自动转。赋值运算的优先级最低,而+=的优先级就不一样了。s = (short) (s+2);你可以这么写,把它俩的和强制类型转换。另外一楼那位说的灰常详细,赞一个
作者: Shimano    时间: 2013-12-6 02:56
解答:
        首先,
                是因为你对“+=”这个赋值运算符没有真正搞明白,
                平时看到的书上讲得过于简单,没有给出s+=2;与s=s+2;有什么区别,所以使用起来你会郁闷。
                其实很简单,记着就好了,不必深层次的理解。
       
        其次,
                可能你还没真正理解:
                强制类型转换、隐含强制类型转换、自动类型转换  三者的概念。
               

解释如下:
        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;执行结果是一样的。



               
               
               


add.jpg (55.22 KB, 下载次数: 21)

基本类型变量间的赋值关系

基本类型变量间的赋值关系

作者: 翼展哈哈    时间: 2013-12-6 10:51
楼主,您好!
        如果前面各位同学的理论讲解,您还不是很明白的话,我给您一个具体的示例吧。
        
        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的运算结果不一定是对的,它只是单纯地可通过编译而已!所以,我的建议是,您只需要记住什么形式可编译通过什么形式不可编译通过,但真正运行的时候还是需要谨慎的!因为程序最终还是要运行成功才行的。
        希望我的解答能给您一些帮助!如果有什么说的不对的地方,请批评指正,共同进步嘛!
      




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2