Java Reference
In-Depth Information
How could you possibly turn this into an infinite loop? The key to solving this puzzle is that >>>= is
a compound assignment operator . (The compound assignment operators are *= , /= , %= , += , -= , <<= ,
>>= , >>>= , &= , ^= , and |= .) An unfortunate fact about the compound assignment operators is that
they can silently perform narrowing primitive conversions [JLS 15.26.2], which are conversions
from one numeric type to a less expressive numeric type. Narrowing primitive conversions can
lose information about the magnitude or precision of numeric values [JLS 5.1.3].
To make this concrete, suppose that you precede the loop with the following declaration:
short i = -1;
Because the initial value of i ( (short)0xffff ) is nonzero, the body of the loop is executed. The
first step in the execution of the shift operation is that the value of i is promoted to an int . All
arithmetic operations do this to operands of type short , byte , or char . This promotion is a
widening primitive conversion, so no information is lost. This promotion performs sign extension,
so the resulting int value is 0xffffffff . This value is then shifted to the right by one bit without
sign extension to yield the int value 0x7fffffff . Finally, this value is stored back into i . In order
to store the int value into the short variable, Java performs the dreaded narrowing primitive
conversion, which simply lops off the high-order 16 bits of the value. This leaves (short)0xffff ,
and we are back where we started. The second and successive iterations of the loop behave
identically, so the loop never terminates.
Similar behavior occurs if you declare i to be a short or byte variable initialized to any negative
value. You will not get an infinite loop if you declare i to be a char , as char values are unsigned,
so the widening primitive conversion that occurs prior to the shift doesn't perform sign extension.
In summary, do not use compound assignment operators on short , byte , or char variables . Such
expressions perform mixed-type arithmetic, which can be confusing in and of itself. Far worse, they
perform an implicit narrowing cast, which can discard information. The results can be disastrous.
The lesson for language designers is that languages should not perform narrowing conversions
silently. One could well argue that Java should have disallowed the use of compound assignment
operators on short , byte , and char variables.
 
 
Search WWH ::




Custom Search