java解惑之表达式之谜(谜题9)

谜题9:半斤

该谜题仅有两行代码:

x+=i;    //合法

x = x + i;    //不合法

对于上面的两个表达式,我们通常都认为第一个表达式是第二个表达式的简写方式,但这并不准确。这两个表达式都被称为赋值表达式。第二个表达式使用的是简单赋值操作符(=),而第一个表达式使用的是复合赋值操作符。在java语言规范中提到,复合赋值等价于简单赋值 E1 = (T)((E1) op (E2)),其中T是E1的类型,除非E1只被计算一次。也就是说,复合赋值表达式自动地将所执行计算的结果转型为其左侧变量的类型。如果结果的类型与该变量的类型相同,则不会有任何影响;若结果的类型比该变量要宽,那么复合赋值操作符将会执行一个窄化原生类型转换,因此,上面的第二个表达式可能会产生一个编译错误。我们可以假设上面代码中的类型如下:

short x = 0;

int i = 123456;

那么 x+=i 将不会产生任何错误,但打印的值却不是123456,而是-7616,因为int类型的数值123456对于short来说太大了,自动产生的转型把int数值的高两位截除了。而对于简单赋值来说,这是非法的,需要我们添加一个显示的转型。总的来说,复合赋值表达式可能是危险的,我们应当避免将复合赋值操作符作用于byte、short或char类型的变量。在将复合赋值操作符作用于int类型的变量时,要确保表达式右侧不是long、float或double类型。在将复合赋值操作符作用于float类型的变量时,要确保表达式右侧不是double类型。这些规则足以防止编译器产生危险的窄化转型,因为复合赋值操作符总是会悄悄地产生一个转型,而这样的转型有可能会悄悄地丢失掉精度或数量值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值