byte b=9 ;
b=b+6 ;
gives compilation error (possible loss of precision )
why does b=9
not give error whereas b=b+9
give loss
This code gives an error...
byte b=9;
b=b+6;
... because of the binary numeric promotion occurring with b+6
, which promotes b
to int
to add the quantities. Section 5.6.2 of the JLS talks about this:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
(emphasis mine)
To get b=b+6
to compile, you can explicitly cast the result back to byte
:
b = (byte) (b + 6);
But what about b=9
and b+=6
? Why do they compile without error?
9
is a constant expression, and the Java compiler treats it differently, with respect to narrowing assignments.
Section 5.2 of the JLS talks about assignment conversion.
In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:
A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
It can be narrowed if it's a constant expression, so that the compiler knows the value, and it knows that overflow wouldn't occur. That is why b=9
isn't an error.
Section 15.26 of the JLS talks about the compound assignment operators.
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.
That is, the result, even if it's promoted to int
, will be implicitly casted back to byte
. Note that this may overflow without error; byte += 10009
will "succeed" with overflow.
When adding bytes, the result is an integer, so that you don't get byte overflow.
You should try casting it:
b=(byte)(b+9);
During expression evaluation there is an implicit type casting to int
, due to the promotion rules in java
So intead of :
byte b=1;
b=b+1; //will give error
Write:
b=(byte)b+1;
Here are some links you can refer:
Link 1
Link 2
Link 3
The expression
b = b + 6
is an integer operation as og JLS §4.2.2. As stated in the JLS, each such operation is of type int
or long
(here: int
). So the result is also of type int
and it must be cast to byte
if you want to assign it to such a variable.
On the other hand, JLS §15.26.2 explains the rules for the compound assignment operator. In short:
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.
This clearly tells us that the compound assignment operator +=
implicitly does the cast.