You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java中double转int的Lossy Conversion异常:为何+=运算符无报错?

为什么+=不会触发损失转换错误?

这事儿的核心在于Java对直接赋值和**复合赋值运算符(比如+=)**的处理规则完全不同,咱们一步步拆解清楚:

先看代码示例1的报错原因

这段代码直接把Math.pow()返回的double值赋值给int变量:

class Lossy { 
    public static void main(String args[]) { 
        int sum; 
        sum=Math.pow(2,3); // 这里触发Possible Lossy Conversion错误
        System.out.println (sum); 
    } 
}

Math.pow()返回的是double类型(比如这里的8.0),而int是范围更小的整数类型。把大范围类型直接赋值给小范围类型属于窄化转换——这种转换可能会丢失精度(比如如果结果是8.5,转成int就会丢掉小数部分变成8),所以Java编译器要求你必须显式写强制类型转换(比如sum = (int) Math.pow(2,3);),否则就会抛出错误,防止你不小心丢失数据。

再看代码示例2为什么能正常编译

修改后的代码用了+=复合赋值:

class Lossy { 
    public static void main(String args[]) { 
        int sum=2; 
        sum+=Math.pow(2,3); // 这里完全没问题
        System.out.println (sum); // 输出10
    } 
}

Java语言规范里对复合赋值运算符有特殊规定:E1 op= E2这种写法,等价于E1 = (T)((E1) op (E2)),其中TE1的类型。翻译到咱们的例子里,就是编译器会自动把代码转换成:

sum = (int)(sum + Math.pow(2,3));

具体执行步骤是:

  1. 先把sumint2自动转换成double类型(变成2.0
  2. Math.pow(2,3)返回的8.0相加,得到10.0
  3. 最后自动把这个double结果强制转换成int类型(变成10),赋值给sum

因为复合赋值运算符会自动帮你加上强制类型转换,编译器默认你已经知晓这里可能存在精度损失并接受这种转换,所以不会再抛出错误。

内容的提问来源于stack exchange,提问作者Vedant Pareek

火山引擎 最新活动