The short answer#
Read the expression left to right. Whatever you meet first happens first.
- In
x++you meetxfirst — so you get the value first, and the increment happens after. - In
++xyou meet++first — so the increment happens first, and you get the new value.
Both add exactly one to x. The only thing that differs is which value the expression hands back. If nothing is using that value, the two are interchangeable.
An increment does two separate things — it changes the variable, and it produces a value. Prefix and postfix change the variable identically. They differ only in the value they produce.
Seeing the difference#
The difference is invisible until something consumes the value. Printing it is the easiest way to make it visible:
int tickets = 5;
System.out.println(tickets++); // prints the value BEFORE
System.out.println(tickets); // the variable afterwards
5
6
Now move the ++ to the front and nothing else:
int tickets = 5;
System.out.println(++tickets); // prints the value AFTER
System.out.println(tickets);
6
6
The variable ends at 6 in both cases. Only the first printed line changed.
On a line of its own, they are the same#
int a = 7;
int b = 7;
a++; // value produced: discarded
++b; // value produced: discarded
a is 8, b is 8
This is why i++ and ++i are interchangeable in the update part of a for loop — that value is thrown away, so the choice makes no difference. Both of these visit 0, 1 and 2:
for (int i = 0; i < 3; i++) // 0 1 2
for (int i = 0; i < 3; ++i) // 0 1 2
The four combinations, side by side#
Start each row from int n = 4;. "Expression gives" is what an assignment, a comparison or a println would receive.
| Written | Expression gives | n becomes |
|---|---|---|
n++ | 4 — the old value | 5 |
++n | 5 — the new value | 5 |
n-- | 4 — the old value | 3 |
--n | 3 — the new value | 3 |
Decrement follows exactly the same rule; there is nothing extra to learn for --.
Captured into a variable#
int count = 4;
int stored = count++; // stored = 4, count = 5
int count = 4;
int stored = ++count; // stored = 5, count = 5
A useful way to remember which is which: with prefix, the two always agree. With postfix they disagree by one, because the variable has moved on but the captured value has not.
The trap: assigning a variable to itself#
This one is worth memorizing, because it compiles cleanly and does nothing:
int value = 3;
value = value++;
System.out.println(value);
3
Java works out the right-hand side first, and postfix produces 3. The variable is then bumped to 4. Then the assignment writes the saved 3 back on top — overwriting the increment. The last thing to happen wins, and the last thing to happen is the assignment.
Swap in prefix and the saved value matches, so it survives:
int value = 3;
value = ++value; // 4
Neither line is code you should write. value++; on its own is what was meant, and it is unambiguous.
Inside a condition, the choice changes the branch#
This is where the distinction stops being trivia. Same starting value, same comparison, one character moved:
int flag = 0;
if (flag++ != 1) { /* A */ } else { /* B */ }
The comparison sees 0 — the value before the increment. 0 != 1 is true, so branch A runs. flag still ends at 1.
int flag = 0;
if (++flag != 1) { /* A */ } else { /* B */ }
The comparison sees 1. 1 != 1 is false, so branch B runs. flag ends at 1 here too.
The variable finishes in the same state either way. The program does not, because a different branch ran. When you trace code by hand, track the expression's value and the variable's value as two separate things.
More than one increment in the same expression#
Evaluation runs left to right, and each increment takes effect before the next part is read. Starting from int n = 2;:
| Expression | Works out as | Result |
|---|---|---|
n++ + n++ | 2 + 3 | 5, and n is 4 |
++n + ++n | 3 + 4 | 7, and n is 4 |
n++ * 2 | 2 × 2 | 4, and n is 3 |
Both of the first two increment n twice, so it lands on 4 either way — but the sums differ by two. The same left-to-right rule explains this line:
int step = 1;
System.out.println(step++ + " " + step);
1 2
The first part hands back 1 and leaves the variable at 2, so the second part reads 2. Write expressions like this in an exam answer, never in real code.
Compound assignment: the five shorthands#
+= and friends are a different tool for a related job. Where ++ always adds exactly one, a compound assignment applies any operation and stores the result back:
| Shorthand | Means | From n = 10 |
|---|---|---|
n += 3 | n = n + 3 | 13 |
n -= 3 | n = n - 3 | 7 |
n *= 3 | n = n * 3 | 30 |
n /= 3 | n = n / 3 | 3 |
n %= 3 | n = n % 3 | 1 |
Two notes on that table. /= gives 3 rather than 3.333 because both sides are whole numbers, so this is integer division. And %= stores the remainder, which is why the same numbers give 1.
Watch the character order. n += 3 adds; n =+ 3 is an assignment followed by a plus sign and simply stores 3. The compiler accepts both, so this is a silent bug.
The hidden cast in every compound assignment#
The shorthand is not quite a pure abbreviation. A compound assignment quietly inserts a cast back to the variable's type — and that changes what compiles.
int n = 5;
n = n + 2.9; // does NOT compile
n += 2.9; // compiles, and n becomes 7
The first line is rejected outright:
error: incompatible types: possible lossy conversion from double to int
n = n + 2.9;
^
The second does the same arithmetic, gets 7.9, then truncates it to 7 without a word. It works the same way on a byte, where the result is stranger:
byte small = 10;
small += 300; // compiles
small = small + 300; // does NOT compile
54
The version the compiler rejects is the safe one. The shorthand hides the narrowing that plain assignment refuses to do silently, so a value that does not fit gets wrapped instead of reported. If a compound assignment mixes types, work out the long form in your head and ask whether it would have compiled.
What can and cannot be incremented#
++ is an assignment in disguise, so its operand has to be something you can assign to.
error: unexpected type
total = 5++;
^
required: variable
found: value
A literal has no storage to update. For the same reason, a final variable is rejected:
error: cannot assign a value to final variable LIMIT
It works on more than int, though. char is a numeric type, so ++ moves it to the next character, and floating-point types work too:
char letter = 'a'; letter++; // b
double rate = 1.5; rate++; // 2.5
Where these go wrong#
- Writing
x = x++;. It compiles, it looks like an increment, and it leaves the variable unchanged. Writex++;on its own. - Assuming the branch is the same either way. Inside a condition, prefix and postfix can send the program down different paths from identical starting values.
- Reading
x++as "x is now bigger" and stopping there. Track two things: what the expression gave, and what the variable became. - Trusting
+=to behave like the long form. It hides a cast.byte b = 10; b += 300;compiles and gives 54. - Typing
=+instead of+=. Both compile. Only one adds. - Packing several increments into one expression. It is fair game in an exam and a liability in real code — split it into separate statements.
Test yourself in the free Kestrel Exams app
Topic-selectable practice — offline, no ads, no account.
Practice this topic →Frequently asked questions#
What is the difference between x++ and ++x?
Both add one to x. They differ in the value the expression hands back: x++ hands back the value from before the increment, and ++x hands back the value after it. Read the expression left to right and whatever you meet first happens first. If nothing uses that value, the two forms behave identically.
Does it matter whether I write i++ or ++i in a for loop?
No. The update part of a for statement discards the value of the expression, so both forms do exactly the same thing and the loop runs identically. The choice there is purely a matter of style.
Why does value = value++ leave the variable unchanged?
The right-hand side is worked out first and produces the old value. The variable is then incremented. Finally the assignment writes the saved old value back over it, discarding the increment. The assignment happens last, so it wins. Write value++ on its own line instead.
What are the five compound assignment operators?
They are +=, -=, *=, /= and %=. Each applies the operation to the variable and stores the result back, so n += 3 does the same job as n = n + 3.
Is n += 3 exactly the same as n = n + 3?
Not quite. A compound assignment silently inserts a cast back to the variable's type. That means int n = 5; n += 2.9; compiles and gives 7, while n = n + 2.9; is rejected as a possible lossy conversion. The shorthand can hide a narrowing that plain assignment would refuse to do.
Can I use ++ on something that is not an int?
Yes. It works on any numeric variable, including char, double, long and byte. Incrementing a char moves it to the next character code, so a char holding the letter a becomes b. What you cannot increment is a literal or a final variable, because ++ has to store a new value somewhere.
