Increment and Decrement Operators in Java

Java's increment (++) and decrement (--) operators are shortcuts for adding or subtracting one from a variable. They come in two forms β€” prefix (++x) and postfix (x++) β€” and the difference between them causes more bugs than any other operator in the language.

The core rule

Both forms change the variable by 1. The difference is the value the expression yields:

  • ++x increments first, then yields the new value.
  • x++ yields the old value, then increments.

Same logic for --x and x--.

Minimal examples

int a = 5;
int b = ++a;   // a becomes 6, b takes the new value: 6

int c = 5;
int d = c++;   // d takes the old value: 5, then c becomes 6

System.out.println(a + " " + b); // 6 6
System.out.println(c + " " + d); // 6 5

Combined usage in expressions

int x = 10;
int y = x++ + ++x;
// 1. x++ evaluates to 10, then x becomes 11
// 2. ++x : x becomes 12, evaluates to 12
// 3. y = 10 + 12 = 22
System.out.println(y + " " + x); // 22 12

Expressions that modify the same variable multiple times are legal but hard to read. Avoid them in production code.

In a for loop β€” no practical difference

for (int i = 0; i < 5; i++) { ... }
for (int i = 0; i < 5; ++i) { ... }

Both loops behave identically because the value of the increment expression is discarded. Micro-benchmark myths about ++i being faster do not apply to Java primitives β€” the compiler emits the same bytecode (iinc). The distinction matters only in C++ with non-trivial iterators.

Common pitfalls

1. Increment inside array access

int[] arr = {10, 20, 30, 40, 50};
int i = 0;
System.out.println(arr[i++] + arr[++i]);
// Reads arr[0] = 10, then i=1, then ++i β†’ i=2, arr[2] = 30 β†’ total = 40
// Hard to read ; prefer:
System.out.println(arr[0] + arr[2]);

2. Increment on the wrong side of assignment

int score = 0;
score = score++;   // ❌ score stays at 0 !
// Explanation: right side yields old value (0), increments score to 1,
// then the assignment writes the yielded 0 back into score.

This looks like a bug but is valid Java. Always write score++; or score = score + 1; as separate statements.

3. Boolean misunderstanding

++ and -- don't apply to booleans. For flip-flopping a boolean, use b = !b;.

4. Increment on the wrapper Integer

Integer i = 5;
i++; // works via auto-unboxing, auto-reboxing
// Under the hood:
Integer newI = Integer.valueOf(i.intValue() + 1);

Fine for occasional use, but expensive in hot loops due to allocation pressure. Use primitive int when performance matters.

Compound assignment as a safer alternative

When you want to increment by a specific amount, use +=:

counter += 1;  // equivalent to counter++ but less ambiguous
counter += 2;  // cannot be expressed with ++ at all

Threading note

i++ on a shared int field is not atomic. It reads, adds, and writes in three steps β€” two threads can interleave and lose updates. Use one of:

  • java.util.concurrent.atomic.AtomicInteger with .incrementAndGet() (equivalent to ++i) or .getAndIncrement() (equivalent to i++).
  • synchronized block around the read-modify-write.
  • LongAdder when the counter is heavily contended and you rarely read.

Operator precedence cheat sheet

PriorityOperators
Highestpostfix x++, x--
prefix ++x, --x, unary +, -, !, ~
multiplicative *, /, %
additive +, -

In 5 * x++, the increment happens after the multiplication uses the current value.

Style guideline

  1. Use ++ and -- as stand-alone statements or inside a for loop.
  2. Never combine them with an assignment to the same variable.
  3. Avoid mixing them inside a larger expression β€” readability beats cleverness.
  4. On shared state, use atomic variables.

Following these four rules eliminates essentially every bug this operator family can create.