为何x *= 0.90无报错,x = x*0.90却触发损失性转换错误?
为什么Java中
x *= y和x = x * y的行为不同? 核心原因是Java的复合赋值运算符(如*=)会自动执行隐式类型转换,而普通赋值语句不会做这个操作。
分析第一段代码
int x = 18; x *= 0.90; System.out.println(x);
x *= 0.90并不是简单等价于x = x * 0.90,它的实际执行逻辑是x = (int)(x * 0.90):
- 先计算
x * 0.90,得到double类型的结果16.2 - 编译器自动将这个double结果强制转换为int类型,直接截断小数部分得到
16 - 赋值给int类型的x,所以能正常编译运行,最终输出
16
分析第二段代码
int x = 18; x = x * 0.90; System.out.println(x);
这里x * 0.90计算后得到的是double类型的16.2,而直接赋值给int类型的x时:
Java不允许自动进行有损转换(从double转int会丢失小数部分的精度),编译器会明确报错提示incompatible types: possible lossy conversion from double to int,必须显式添加强制转换x = (int)(x * 0.90)才能通过编译。
本质规则
根据Java语言规范,复合赋值运算符E1 op= E2的等效逻辑是:E1 = (T)((E1) op (E2))
其中T是E1的原始类型。这就意味着复合赋值会自动把运算结果转换为左侧变量的类型,而普通赋值语句没有这个自动转换的步骤。
内容的提问来源于stack exchange,提问作者pprav
相关产品推荐
相关产品推荐

