关于java:为什么* =隐式地将一个浮点数转换为int时没有给出任何错误?

Why does *= not give any errors when implicitly casting a float to an int?

本问题已经有最佳答案,请猛点这里访问。

我之前遇到过一种情况,我尝试了以下两个代码位:

1
2
int score = 100;
score = score * 1.05;

1
2
int score = 100;
score *= 1.05;

第一个失败了(显然,我正试图隐式地将一个float强制转换为int)。但是第二个非常好。编译器没有抱怨,也没有收到任何运行时错误。为什么第二个有效,而第一个无效?据我所知,x *= y只是x = x * y的简写。


复合赋值运算符的行为与它们的"扩展"版本稍有不同。引用JLS第15.26.2节:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

它隐式转换回左侧变量的类型,因此将float转换为int时不会出错;它已经隐式转换为int

=运算符不发生这种情况,该运算符受JLS第5.2节"分配转换"的管辖:

Assignment contexts allow the use of one of the following:

  • an identity conversion (§5.1.1)

  • a widening primitive conversion (§5.1.2)

  • a widening reference conversion (§5.1.5)

  • a boxing conversion (§5.1.7) optionally followed by a widening reference conversion

  • an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

接着讨论了一种可能的变窄转换,但仅限于常数表达式,并且仅限于常数表达式为bytecharshortint,两者在这里都不适用。


第一个

1
2
int score = 100;
score = score * 1.05;

基本上是说:

1
2
int score = 100;
score = (float)(score * 1.05);

这是因为如果用一个整数乘以一个浮点数,就会得到一个浮点数。这样就无法分配给整数。

然而

1
2
int score = 100;
score *= 1.05;

基本上意味着

1
2
int score = 100;
score = (int)(score * 1.05);

这是因为您没有分配浮点,计算是在分配的同时完成的,因此首先将转换为int。

这对我来说是有意义的。希望它有帮助


如果使用:

1
2
int score=100;
score *=1.05;

这相当于:

1
score=(int)(score*1.05);

这里更详细地解释了:http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html 15.26.2

形式e1 op=e2的复合赋值表达式等价于e1=(t)((e1)op(e2)),其中t是e1的类型,但e1只计算一次。