2.4 More Assignment Operators

Java contains a number of assignment operators in addition to the basic one that we have already seen.

As an example, a statement of the form < identifier > += < expression >; is equivalent to a statement of the form

< identifier > = < identifier > + (< expression >);

This can be very useful whenever we want to add a quantity to the value of a variable.

Example 1

(a) The statement n += 3; is equivalent to n = n + (3);

(b) The statement x += 2.5; is equivalent to x = x + (2.5);

(c) The statement m += n - 2; is equivalent to m = m + (n - 2);

Assignment can also be combined with the other four basic arithmetic operators.

                  -=   *=   /=   %=

In each case, the effect is similar to that seen with +=, as illustrated in the next example.

Example 2

(a) The statement x -= y + 1; is equivalent to x = x - (y + 1);

(b) The statement m /= n * p; is equivalent to m = m / (n * p);

(c) The statement n *= 5; is equivalent to n = n * (5);

Java permits the use of multiple assignments in one statement. In such statements, the assignment operators are applied from right to left, rather than from left to right.

Example 3

The statement i = j = k = 1;

first assigns the value 1 to k, then the value that has been assigned to k is assigned to j, and finally the value that has been assigned to j is assigned to i. Thus, the given statement is equivalent to i = (j = (k = 1));

All types of assignment operators can be mixed in a multiple assignment statement. All varieties of assignment operator have the same precedence, lower than that of any other Java operator. As with simple assignments, evaluation again takes place from right to left.

Example 4

Suppose that i, j, and k are int variables with values 1, 2, and 3 respectively.

Then the statement i /= j -= k + 2; would be evaluated as follows:

      i /= j = j - (k + 2);
      i /= j = 2 - (3 + 2);
      i /= j = -3;
      i = i / (j);
      i = 1 / (-3);
      i = 0;

The final values of i, j, and k would be 0, -3, and 3 respectively.

The next table summarizes the precedence rules for the operators that we have seen so far. Operators with higher precedence appear above those with lower precedence. Parentheses can be used to alter the order of evaluation.

Operator           Operation

++ -- increment, decrement + - unary plus, minus (< type >) cast to < type > * / % multiplication, division, remainder + - addition/concatenation, subtraction = += -= *= /= %= assignments

In trying to understand how assignment operators behave, it may be helpful to explore the process that occurs in the evaluation of a Java expression. In many ways, assignment operators are like arithmetic operators. An expression containing a mixture of arithmetic and assignment operators will be evaluated using the precedence rules that we have noted previously, with assignments having the lowest precedence. However, when Java evaluates an assignment expression, it also carries out an assignment of a value to a variable. The value of an assignment expression is the value that is assigned to the variable. The actual assignment process is simply a side effect of the evaluation of the expression.

Example 4

The sequence of statements

int i = 4, j = 2;

System.out.println(i += j = 5 + 3 * 4);

is perfectly valid. (Although the code is valid, using a complex and possibly confusing expression like the one shown in the println statement is not recommended. In programming, you should always strive to maximize clarity, not to confuse your readers.) To perform the println, Java must first evaluate its argument. The steps in the evaluation of that expression are shown in the following table.

Evaluation Stage     Expression Value     i     j

Start i += j = 5 + 3 *4 4 2 Multiply 3 by 4 i += j = 5 + 12 4 2 Add 5 plus 12 i += j = 17 4 2 Assign 17 to j i += 17 4 17 Assign 21 to i 21 21 17

The value 21 is then converted to a string and printed. As side effects of the evaluation of the expression, the values of i and j have been set to 21 and 17 respectively.

Exercise 2.4

  1. Suppose that x is a double variable whose value is 3.0 just before each statement is executed. Find the value of x after execution of the statement.
    (a) x *= 2;      (b) x += x;      (c) x *= 2/3;     (d) x /= 15/6;
    
  2. Suppose that, before each statement is executed, the values of the int variables i and j are 4 and 7 respectively. Find their values after execution of the statement.
    (a) j += i;            (b) i *= j;      (c) i -= j--;       (d) i *= --j;   
    (e) j %= --i;          (f) j /= ++i;    (g) i *= ++j + 2;   (h) j *= i-- % 3;
    
  3. Suppose that, before each statement is executed, the values of the int variables i, j, and k are 3, 2, and 1 respectively. Find their values after execution of the statement.
    (a) i = j = k;           (b) i = j += k;
    (c) i *= j = k + 2;      (d) i -= j += k++;
    (e) i += j *= ++k + 1 ;  (f) i %= j = k++ % 4;
  4. State the error in each statement.
    (a) i + 3 += j; (b) i *= j - 2 = k;