I see that the below code:
byte b = 127;
b = b + 1;
b = b + 1;
System.out.println(b);
leads to boundary checking during runtime, and the first addition takes b out of range, leading to following error -
Main.java:11: error: incompatible types: possible lossy conversion from int to byte b=b+1; Main.java:12: error: incompatible types: possible lossy conversion from int to byte b=b+1;
However, when I use the shorthand or increment, as:
byte b = 127;
b += 1;
b++;
System.out.println(b);
we find that the value of byte 'wraps around', giving the output
-127
Why this anomaly? What actually prevents the addition from wrapping around(as C does), or increment/shorthand from doing boundary checks?
Why this anomaly?
When you add a byte
plus an int
you get an int
so when you assign it to a byte
it complains. However when you do
b += 1;
There is an implicit cast in this operation which is not obvious but is in the JLS. A clearer example is
char ch = '0';
ch /= 0.9; // << an implicit cast occurs here.
System.out.println(ch); // 5
similarly, when you do
b++;
for this to compile, it has to assume an overflow is possible.
In short, the difference is that
b = b + 1;
has two operators instead of one, and this results in a warning that an overflow might occur.
Note: This doesn't apply to int
or long
types as you can do
int i = Integer.MAX_VALUE;
i = i + 1; // no warning as int is not widened to long
long l = Long.MAX_VALUE;
l = l + 1; // no warning as long is the widest type.
Even if Java 10 might have Long2
for 128 bit integers (and it might) long
still won't be widened.