Arithmetic Compound Assignment Operators: *=, /=, %=, +=, -=
A compound assignment operator has the following syntax:
variable op= expression
and the following semantics:
variable = (type) ((variable) op (expression))
The type of the variable is type and the variable is evaluated only once. Note the cast and the parentheses implied in the semantics. Here op= can be any of the compound assignment operators specified in Table 2.18. The compound assignment operators have the lowest precedence of all the operators in Java, allowing the expression on the right-hand side to be evaluated before the assignment. Table 2.22 defines the arithmetic compound assignment operators.
Table 2.22 Arithmetic Compound Assignment Operators
Expression | Given T as the numeric type of x, the expression is evaluated as: |
x *= a | x = (T) ((x) * (a)) |
x /= a | x = (T) ((x) / (a)) |
x %= a | x = (T) ((x) % (a)) |
x += a | x = (T) ((x) + (a)) |
x -= a | x = (T) ((x) – (a)) |
The implied cast operator, (T), in the compound assignments becomes necessary when the result must be narrowed to the target type. This is illustrated by the following examples:
int i = 2;
i *= i + 4; // (1) Evaluated as i = (int) ((i) * (i + 4)).
Integer iRef = 2;
iRef *= iRef + 4; // (2) Evaluated as iRef = (Integer) ((iRef) * (iRef + 4)).
byte b = 2;
b += 10; // (3) Evaluated as b = (byte) (b + 10).
b = b + 10; // (4) Will not compile. Cast is required.
At (1) the source int value is assigned to the target int variable, and the cast operator (int) in this case is an identity conversion (i.e., conversion from a type to the same type). Such casts are permitted. The assignment at (2) entails unboxing to evaluate the expression on the right-hand side, followed by boxing to assign the int value. However, at (3), as the source value is an int value because the byte value in b is promoted to int to carry out the addition, assigning it to a target byte variable requires an implicit narrowing conversion. The situation at (4) with simple assignment will not compile because implicit narrowing conversion is not applicable.
The variable is evaluated only once in the expression, not twice, as one might infer from the definition of the compound assignment operator. In the following assignment, a[i] is evaluated just once:
int[] a = new int[] { 2020, 2030, 2040 };
int i = 2;
a[i] += 1; // Evaluates as a[2] = a[2] + 1, and a[2] gets the value 2041.
Implicit narrowing conversions are also applied to increment and decrement operators (p. 69).
Boolean logical compound assignment operators are covered in ยง2.14, p. 78.