الإسناد والإسناد المركّب
في هذا الدرس 11 موضوعات
هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.
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 + 5style updates, and their shorter forms+=,-=,*=,/=,%=. - Predict the value of
x *= 2 + 1and explain why it is not(x * 2) + 1. - Use chained assignment such as
a = b = 0and say how it is evaluated. - Explain the hidden cast in compound assignment, with an
intexample. - Use
+=on aString.
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:
- Calculate the right side using the current values.
- 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:
| Shortcut | Same as | Meaning |
|---|---|---|
x += 5 | x = x + 5 | add 5 |
x -= 5 | x = x - 5 | subtract 5 |
x *= 5 | x = x * 5 | multiply by 5 |
x /= 5 | x = x / 5 | divide by 5 (integer division for int) |
x %= 5 | x = x % 5 | keep 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:
int x = 5;
x *= 2 + 1; // x = x * (2 + 1), so x is 15, not 11The 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:
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 intThe 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:
byte small = 100;
small += 100; // compiles; the true result 200 wraps to -56So += 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):
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:
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)
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):
15
30
8
0
15
7 7 7
12
-56
Hi there3Follow 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)
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);
}
}9 3
17
11The 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.
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);
}
}subtotal: 2599
with tax: 2806
tip: 280
orders: 1Check 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
intwraps silently when it passes the maximum. Large totals (bytes served, microseconds elapsed, cents across many orders) should uselong, as BEG-009 explained. - Updates from several threads.
x += 1is 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, expecting11. - Correct: the whole right side is calculated first, so the result is
5 * 3, which is15.
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;.
أظهر الحل A1
A1. count += 1;, price *= 2;, left -= used;.
A2. With int x = 20;, what is x after x -= 5; and then x /= 4;?
أظهر الحل 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;?
أظهر الحل 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;
أظهر الحل 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:
int a = 7;
int b = 2;
a %= b;
b += a * 5;
System.out.println(a + " " + b);أظهر الحل 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 += "!";
أظهر الحل 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.
أظهر الحل 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.
أظهر الحل 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:
- Receive 1250 cents.
- Pay a 399-cent subscription.
- Double the balance (a bonus offer).
- Take away 10 percent (use integer arithmetic,
balanceCents -= balanceCents / 10). - 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 + 1the 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;gives12. +=appends to aString. 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
- What does
x += 3mean? - If
int x = 4;, what isxafterx *= 2 + 3;? - In which order does Java do the two steps of
y = y * 2? - What is
nafterint n = 7; n += 1.9;? - Why can a swap not be written as
a = b; b = a;?
أظهر الإجابات
x = x + 3: add 3 to the current value and store it back.20, because the right side2 + 3is5.- First it calculates
y * 2using the currenty; then it stores the result iny. 8.7 + 1.9is8.9, and the hidden cast keeps only8.- The first line overwrites
abefore its old value has been saved, so both variables end up with the oldb.
References
- Oracle, The Java Language Specification, Java SE 21, Chapter 15: Expressions. Section 15.26.2 says
E1 op= E2is equivalent toE1 = (T)((E1) op (E2))withE1evaluated 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 intcame from compiling and running with JDK 21. The remark thatx += 1is 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.
التطبيق
طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.
تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.