While decompiling your code will explain what Java is doing, the reason why it’s doing it can be generally found in the language specification. But before we go into that, we have to establish a few important concepts:
-
A literal numeral is always interepreted as an
int.An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (ยง4.2.1).
-
A
bytecan only hold an integer value between -128 and 127, inclusive. -
An attempt to assign a literal that is larger than the type that can hold it will result in a compilation error. This is the first scenario you’re encountering.
So we’re back to this scenario: why would adding two bytes that are clearly more than what a byte can handle not produce a compilation error?
It won’t raise a run-time exception because of overflow.
This is the scenario in which two numbers added together suddenly produce a very small number. Due to the small size of byte‘s range, it’s extremely easy to overflow; for example, adding 1 to 127 would do it, resulting in -128.
The chief reason it’s going to wrap around is due to the way Java handles primitive value conversion; in this case, we’re talking about a narrowing conversion. That is to say, even though the sum produced is larger than byte, the narrowing conversion will cause information to be discarded to allow the data to fit into a byte, as this conversion never causes a run-time exception.
To break down your scenario step by step:
- Java adds
a = 127andb = 5together to produce 132. - Java understands that
aandbare of typebyte, so the result must also be of typebyte. - The integer result of this is still 132, but at this point, Java will perform a cast to narrow the result to within a byte – effectively giving you
(byte)(a += b). - Now, both
aandzcontain the result -124 due to the wrap-around.