Variable Increment and Decrement Operators: ++, — – Basic Elements, Primitive Data Types, and Operators

2.10 Variable Increment and Decrement Operators: ++, —

Variable increment (++) and decrement (–) operators come in two flavors: prefix and postfix. These unary operators have the side effect of changing the value of the arithmetic operand, which must evaluate to a variable. Depending on the operator used, the variable is either incremented by 1 or decremented by 1.

These operators cannot be applied to a variable that is declared final and that has been initialized, as the side effect would change the value in such a variable.

These operators are useful for updating variables in loops where only the side effect of the operator is of interest.

The Increment Operator ++

The prefix increment operator has the following semantics: ++i adds 1 to the value in i, and stores the new value in i. It returns the new value as the value of the expression. It is equivalent to the following statements:

i += 1;
result = i;
return result;

The postfix increment operator has the following semantics: j++ adds 1 to the value in j, and stores the new value in j. It returns the original value that was in j as the value of the expression. It is equivalent to the following statements:

result = j;
j += 1;
return result;

The Decrement Operator —

The prefix decrement operator has the following semantics: –i subtracts 1 from the value of i, and stores the new value in i. It returns the new value as the value of the expression. It is equivalent to the following statements:

i -= 1;
result = i;
return result;

The postfix decrement operator has the following semantics: j– subtracts 1 from the value of j, and stores the new value in j. It returns the original value that was in j as the value of the expression. It is equivalent to the following statements:

result = j;
j -= 1;
return result;

This behavior of decrement and increment operators applies to any variable whose type is a numeric primitive type or its corresponding numeric wrapper type. Necessary numeric promotions are performed on the value 1 and the value of the variable. Before the new value is assigned to the variable, it is subjected to any narrowing primitive conversion and/or boxing that might be necessary.

Here are some examples that illustrate the behavior of increment and decrement operators:

Click here to view code image

// (1) Prefix order: increment/decrement operand before use.
int i = 10;
int k = ++i + –i;  // ((++i) + (–i)). k gets the value 21 and i becomes 10.
–i;                // Only side effect utilized. i is 9. (expression statement)

Integer iRef = 11;  // Boxing on assignment
–iRef;             // Only side effect utilized. iRef refers to an Integer
                    // object with the value 10. (expression statement)
k = ++iRef + –iRef;// ((++iRef) + (–iRef)). k gets the value 21 and
                    // iRef refers to an Integer object with the value 10.
// (2) Postfix order: increment/decrement operand after use.
long j = 10;
long n = j++ + j–; // ((j++) + (j–)). n gets the value 21L and j becomes 10L.
j++;                // Only side effect utilized. j is 11L. (expression statement)

An increment or decrement operator, together with its operand, can be used as an expression statement (§3.3, p. 101).

Execution of the assignment in the second declaration statement under (1) proceeds as follows:

Click here to view code image

k = ((++i) + (–i))          Operands are evaluated from left to right.
k = ( 11   + (–i))          Side effect: i += 1, i gets the value 11.
k = ( 11   +  10)            Side effect: i -= 1, i gets the value 10.
k = 21

Execution of the expression statement –iRef; under (1) proceeds as follows:

  • The value in the Integer object referred to by the reference iRef is unboxed, resulting in the int value 11.
  • The value 11 is decremented, resulting in the value 10.
  • The value 10 is boxed in an Integer object, and this object’s reference value is assigned to the reference iRef.
  • The int value 10 of the expression statement is discarded.

Expressions where variables are modified multiple times during the evaluation should be avoided because the order of evaluation is not always immediately apparent.

We cannot associate increment and decrement operators. Given that a is a variable, we cannot write (++(++a)). The reason is that any operand to ++ must evaluate to a variable, but the evaluation of (++a) results in a value.

In the next example, both binary numeric promotion and an implicit narrowing conversion are performed to achieve the side effect of modifying the value of the operand. The int value of the expression (++b) (i.e., 11) is assigned to the int variable i. The side effect of incrementing the value of the byte variable b requires binary numeric promotion to perform int addition, followed by an implicit narrowing conversion of the int value to byte to assign the value to variable b.

Click here to view code image

byte b = 10;
int  i = ++b;        // i is 11, and so is b.

The following example illustrates applying the increment operator to a floating-point operand. The side effect of the ++ operator is overwritten by the assignment.

Click here to view code image double x = 4.5;
x = x + ++x;         // x gets the value 10.0.