Skip to content
Ameen Abozaid
PublishedBEG-010-L03

Assignment and compound assignment

  • Lesson 3 of 6
  • 12 min read
  • Beginner
On This Lesson 11 topics

Lesson Overview

You have used = since the first variable you declared. This lesson looks at it properly, because = is an operator like the others: it has a left side, a right side, and a clear order in which things happen. Then it introduces the compound assignment operators such as += and *=, which are shortcuts for updating a variable using its own current value.

Think of the labeled box from BEG-009. = means "work out the value on the right, then put it into the box on the left". x += 5 means "take what is in the box, add 5, and put the result back in the same box". Programs do this constantly: totals grow, counters go up, balances shrink.

Why this matters: nearly every loop and every running total in a backend uses an update like total += price. Knowing exactly what the shortcut does, including a hidden type cast, keeps you from small bugs that compile without a single warning.

This lesson builds on Lessons 1 and 2 (expressions and operators) and on variables and conversions from BEG-009.

Learning Objectives

By the end of this lesson you will be able to:

  • Explain that = evaluates the right side first and then stores the result in the left variable.
  • Read and write x = x + 5 style updates, and their shorter forms +=, -=, *=, /=, %=.
  • Predict the value of x *= 2 + 1 and explain why it is not (x * 2) + 1.
  • Use chained assignment such as a = b = 0 and say how it is evaluated.
  • Explain the hidden cast in compound assignment, with an int example.
  • Use += on a String.

Written Explanation

= is an action, not an equation

In algebra, x = x + 1 is nonsense. In Java it is an instruction with a clear order:

  1. Calculate the right side using the current values.
  2. Store the result in the variable on the left.

So with int x = 4;, the statement x = x * x + 1; computes 4 * 4 + 1, which is 17, and only then replaces the old 4 with 17. The old value is used up before the new one is stored. That is why you can safely use a variable on both sides.

The left side must be a variable (a box). 5 = x is an error, because 5 is a value, not a place to store something.

Assignment is also an expression: x = 7 has a value (the value stored), which is what makes chaining possible.

Chained assignment

a = b = c = 7; stores 7 in all three variables. The Java Tutorials state that assignment operators are evaluated from right to left, so this is read as a = (b = (c = 7)): first c gets 7, that value goes to b, then to a. Every variable must already be declared (int a, b, c;). Use it sparingly; one assignment per line is easier to read.

Compound assignment

Updating a variable from its own value is so common that Java has shortcuts:

ShortcutSame asMeaning
x += 5x = x + 5add 5
x -= 5x = x - 5subtract 5
x *= 5x = x * 5multiply by 5
x /= 5x = x / 5divide by 5 (integer division for int)
x %= 5x = x % 5keep the remainder when divided by 5

All the rules from Lesson 1 still apply: with int x, the shortcut x /= 2 does integer division.

The right side is calculated completely first

With a compound operator, the whole right side is evaluated before it is combined with the variable. That is the same as putting parentheses around it:

java
int x = 5;
x *= 2 + 1;   // x = x * (2 + 1), so x is 15, not 11

The Java Language Specification defines E1 op= E2 as E1 = (T)((E1) op (E2)), where T is the type of E1, apart from the detail that E1 is evaluated only once. Notice the parentheses around E2. They are the reason x *= 2 + 1 multiplies by 3.

The hidden cast

The (T) in that definition is a cast back to the type of the variable, written for you. It matters when the right side has a wider type than the variable:

java
int n = 10;
n += 2.7;        // compiles: n = (int) (n + 2.7), so n is 12
n = n + 2.7;     // does NOT compile: possible lossy conversion from double to int

The long form is refused by the compiler, as you learned in BEG-009, because it would silently lose the .7. The short form quietly casts and loses it anyway. Neither the cast nor the data loss is shown anywhere in your code. The same hidden cast can hide overflow:

java
byte small = 100;
small += 100;    // compiles; the true result 200 wraps to -56

So += is convenient, and it also turns off a safety check. Use it freely with matching types, and think twice when the right side is a different type.

+= on text

A String accepts += too, and it means "append". It builds a new string and assigns it (BEG-009 showed that strings never change in place):

java
String s = "Hi";
s += " there";   // "Hi there"
s += 1 + 2;      // 1 + 2 is calculated first (3), so "Hi there3"

Only += works on a String. -= or *= do not.

Swapping two values

Because the right side is calculated before storing, a swap needs a helper box:

java
int temp = a;
a = b;
b = temp;

Writing a = b; b = a; fails because the first line overwrites a before it has been saved.

Examples

Example 1: a value changing step by step (simple)

java
public class Assign {
    public static void main(String[] args) {
        int total = 10;
        total += 5;
        System.out.println(total);
        total *= 2;
        System.out.println(total);
        total -= 4;
        total /= 3;
        System.out.println(total);
        total %= 4;
        System.out.println(total);
        int x = 5;
        x *= 2 + 1;
        System.out.println(x);
        int a, b, c;
        a = b = c = 7;
        System.out.println(a + " " + b + " " + c);
        int n = 10;
        n += 2.7;
        System.out.println(n);
        byte small = 100;
        small += 100;
        System.out.println(small);
        String s = "Hi";
        s += " there";
        s += 1 + 2;
        System.out.println(s);
    }
}

Output (JDK 21):

text
15
30
8
0
15
7 7 7
12
-56
Hi there3

Follow total: 10, then 15, then 30, then 26 (not printed), then 26 / 3 is 8 with integer division, then 8 % 4 is 0. Everything from x onward illustrates a rule from the explanation.

Example 2: swap and self-reference (practical)

java
public class Swap {
    public static void main(String[] args) {
        int a = 3;
        int b = 9;
        int temp = a;
        a = b;
        b = temp;
        System.out.println(a + " " + b);
        int x = 4;
        x = x * x + 1;
        System.out.println(x);
        int y = 1;
        y = y + y * 10;
        System.out.println(y);
    }
}
text
9 3
17
11

The swap needs temp because storing into a destroys the old value. In the last line, y * 10 is evaluated first (10), then added to the old y (1), and 11 is stored.

Example 3: a running cart total (realistic)

All amounts are whole cents, following the money advice from BEG-009.

java
public class Cart {
    public static void main(String[] args) {
        int totalCents = 0;
        totalCents += 1250 * 2;
        totalCents += 399;
        int discount = 300;
        totalCents -= discount;
        System.out.println("subtotal: " + totalCents);
        totalCents += totalCents * 8 / 100;
        System.out.println("with tax: " + totalCents);
        int tipCents = 0;
        tipCents += totalCents / 10;
        System.out.println("tip: " + tipCents);
        int orders = 0;
        orders += 1; orders += 1; orders -= 1;
        System.out.println("orders: " + orders);
    }
}
text
subtotal: 2599
with tax: 2806
tip: 280
orders: 1

Check the tax line by hand: 2599 * 8 / 100 evaluates left to right as 20792 / 100, which is 207 (the .92 is dropped by integer division), and 2599 + 207 is 2806. Real systems must decide a rounding rule for the lost fraction of a cent. That is a business decision, not something to leave to integer division by accident.

Backend Insight

Compound assignment is the heart of accumulation: summing an order, counting requests, totalling bytes. Almost every report or statistic is computed with a variable that starts at a base value (zero for sums, one for products) and is updated with += or *= for each item. Loops, which come later in the course, make this pattern very visible.

Two practical points for backend work:

  • Overflow in accumulators. A counter or total held in an int wraps silently when it passes the maximum. Large totals (bytes served, microseconds elapsed, cents across many orders) should use long, as BEG-009 explained.
  • Updates from several threads. x += 1 is a read, an add, and a write. When many requests update the same variable at the same time, updates can be lost. That is a concurrency topic for a later module; for now remember only that a single line is not necessarily a single step.

Common Mistakes

Mistake 1: Reading x *= 2 + 1 as x * 2 + 1

  • Incorrect: with x = 5, expecting 11.
  • Correct: the whole right side is calculated first, so the result is 5 * 3, which is 15.

Mistake 2: Expecting a compiler warning from += with a wider type

int n = 10; n += 2.7; compiles and gives 12. If you need to keep the decimals, declare n as a double.

Mistake 3: Swapping without a helper

a = b; b = a; leaves both variables with the old b. Use temp.

Mistake 4: = where a comparison is meant

x = 5 stores 5. If you wanted a yes/no question, you need x == 5 (Lesson 2).

Mistake 5: Using a variable before it has a value

int total; total += 5; does not compile, because total was never given a first value. Start accumulators explicitly: int total = 0;.

Exercises

Try each exercise yourself before opening the solutions. Predict the value first.

Level A: Foundation

A1. Rewrite using a compound operator: count = count + 1;, price = price * 2;, left = left - used;.

Show solution A1

A1. count += 1;, price *= 2;, left -= used;.

A2. With int x = 20;, what is x after x -= 5; and then x /= 4;?

Show solution A2

A2. x -= 5 gives 15, and x /= 4 gives 3 (15 / 4 is 3 with the fraction dropped).

A3. What is x after int x = 3; x *= 4 + 2;?

Show solution A3

A3. 18. The right side 4 + 2 is 6, and 3 * 6 is 18.

Level B: Application

B1. Predict the final value of v and w: int v = 6; int w = v; v += 4; w *= 2;

Show solution B1

B1. v is 10 and w is 12. w copied the value 6 when it was created, so changing v did not affect it; then w *= 2 doubled 6.

B2. Predict the output:

java
int a = 7;
int b = 2;
a %= b;
b += a * 5;
System.out.println(a + " " + b);
Show solution B2

B2. a %= b gives 7 % 2, which is 1. Then b += a * 5 gives 2 + 5, which is 7. Output: 1 7.

B3. What does this print, and why? String log = "id"; log += 4 + 5; log += "!";

Show solution B3

B3. id9!. The += right side 4 + 5 is calculated first as the number 9, which is then appended as text.

Level C: Challenge

C1. int score = 90; score += 12.9; What is score? Rewrite the statement so the compiler rejects it, and say what rewrite would keep the decimals.

Show solution C1

C1. score becomes 102 (90 + 12.9 is 102.9, and the cast truncates to 102). The long form score = score + 12.9; is rejected with "possible lossy conversion from double to int". To keep the decimals, declare double score = 90;.

C2. A savings account starts at 100000 cents. Apply, in order: add 5 percent interest, subtract 2500 cents for a fee, then split what remains between 3 equal accounts. Use compound assignment with integers and give the final value for one account. State how many cents the integer division loses.

Show solution C2

C2. Start int cents = 100000;. Interest: cents += cents * 5 / 100; adds 5000, giving 105000. Fee: cents -= 2500; gives 102500. Split: cents /= 3; gives 34166. The lost amount is 102500 % 3, which is 2 cents (3 times 34166 is 102498).

Mini Challenge

Write a program Wallet that starts with int balanceCents = 5000; and applies these changes in order, one compound assignment each, printing the balance after every step:

  1. Receive 1250 cents.
  2. Pay a 399-cent subscription.
  3. Double the balance (a bonus offer).
  4. Take away 10 percent (use integer arithmetic, balanceCents -= balanceCents / 10).
  5. Print how many cents would be left over if the balance were split between 3 people (balanceCents % 3), then split it with /=, and print the share.

Check your work: predict every printed balance on paper before running. The first three should be 6250, 5851, and 11702; the leftover is 2 and the share is 3510.

Summary & Next Lesson

Key takeaways

  • = calculates the right side first, then stores the result in the left variable. It is an action, not an equation.
  • x += n, -=, *=, /=, and %= update a variable from its own value.
  • In x *= 2 + 1 the whole right side is calculated first, as if it had parentheses.
  • Compound assignment casts the result back to the variable's type without warning: int n = 10; n += 2.7; gives 12.
  • += appends to a String. Start accumulators with a value, and use a helper variable to swap.

Next lesson

Next is "Increment, decrement, and precedence": the ++ and -- operators, the difference between putting them before or after a variable, and the rules that decide which part of a long expression is calculated first.

Self-check

  1. What does x += 3 mean?
  2. If int x = 4;, what is x after x *= 2 + 3;?
  3. In which order does Java do the two steps of y = y * 2?
  4. What is n after int n = 7; n += 1.9;?
  5. Why can a swap not be written as a = b; b = a;?
Show answers
  1. x = x + 3: add 3 to the current value and store it back.
  2. 20, because the right side 2 + 3 is 5.
  3. First it calculates y * 2 using the current y; then it stores the result in y.
  4. 8. 7 + 1.9 is 8.9, and the hidden cast keeps only 8.
  5. The first line overwrites a before its old value has been saved, so both variables end up with the old b.

References

  • Oracle, The Java Language Specification, Java SE 21, Chapter 15: Expressions. Section 15.26.2 says E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)) with E1 evaluated once, and that the cast can narrow the result.
  • Oracle, The Java Tutorials: Operators. It lists the assignment operators and states that assignment operators are evaluated right to left.
  • All outputs and the compiler message possible lossy conversion from double to int came from compiling and running with JDK 21. The remark that x += 1 is not an atomic step across threads is a general fact that I did not look up on a page here; it is pointed at a later module.

Practice

Apply this lesson with the module's lab, exercises and quiz.

Lab and exercises Quiz

Marking a lesson complete is optional and you can undo it any time. Your progress stays in this browser.

Continue to next lesson

Type to search levels, phases, modules and lessons.