I have written the code:
int x = 18;
x *= 0.90;
System.out.println(x);
This code printed 16
However, when I wrote
int x = 18;
x = x * 0.90;
System.out.println(x);
it gave me the following error: incompatible types: possible lossy conversion from double to int
I expected both of these code examples to result in the exact same error as x *= y;
is the same as x = x * y;
, but x *= 0.90;
somehow works and x = x * 0.90;
does not. Why is this the case?
Because the Java Language Specifcation (JLS) says so. It's a bit odd, but, when using the compound assignment operators (*=
, +=
, etcetera), the cast is implied.
See JLS §15.26.2 which clearly shows the cast in the example right at the top of that section.
Why does it do that? Well, I don't think SO is the right place to ask 'what were the designers thinking 30 years ago when this part of the JLS spec was written up'.
EDIT: This answer used to mention 'probably because of C' but as comments show, no, in C neither form requires an explicit cast.
The designers of Java generally valued consistency over the sensibility of particular cases. Given byte a,b; int i;
, the expression a & b
will be evaluated by converting the operands to int
, and would thus yield a result type of int
. There was thus no nice way to require a cast for a = (byte)i;
but not require one for a = (byte)(a & b);
. If the expression were written as a &= b;
, there would have been no way to cast the result of the &
operator before performing the assignment. Rather than make the &=
(and other compound assignment) operators useless with byte
, short
, or char
, Java opted to instead include an implicit conversion between the result of the combining operator and the use of the result for the assignment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With