Declaring a variable, assigning to it, and drawing the result as a memory diagram — then printing variables and combining them with arithmetic operators, including the integer division that surprises everyone the first time. Follows Think Java 2e, Chapter 2 (Variables and Operators), Sections 2.1-2.5, pp. 17-23, cross-referenced against The Java Tutorials — Variables.
Subject: Java · 65 slides · code lesson
Open the interactive version of this deck
Title
Think Java 2e · Chapter 2 · Variables and Operators
Sections 2.1-2.5 · pp. 17-23
Objectives
This lesson follows Think Java 2e, Chapter 2 (Variables and Operators), Sections 2.1-2.5, pp. 17-23. Everything on these slides can be checked against those pages.
1. Declare a variable with a type and a name, and say what each of the two parts is for.
2. Distinguish a declaration from an assignment, and explain what 'initialise' means.
3. Draw a memory diagram for a short fragment, and explain why a = b is not a statement of equality.
4. Print the value of a variable and the name of a variable, and say why one needs quotation marks.
5. Evaluate an expression the way Java does: replace each variable by its value, then apply the operators.
6. Predict the result of integer division, and say why 59 / 60 is 0.
Warm-up
Thirty seconds on Chapter 1, because this lesson adds to it rather than replacing it.
Discussion prompt
From memory: what is the difference between print and println? And what does a semicolon do at the end of a line?
Hint: One of them appends something invisible.
Answer:
println appends a newline character; print does not. The semicolon ends a statement — and nearly every statement in this lesson will end with one, including the new kind you are about to meet.
Both come back immediately: Section 2.4 is about printing variables, and every declaration and assignment in this lesson is a statement that needs its semicolon.
Concept
Chapter 1's programs could only print fixed text. This chapter gives you somewhere to put a value, so a program can compute something and hold on to the answer. Everything else in the book is built on that.
Figure (svg): A memory diagram showing two named boxes, hour holding 11 and minute holding 59, each labelled with type int
From here on, the examples often omit the class and method definitions to stay concise. Assume every fragment lives inside a main method like the one you wrote in Chapter 1.
Downey & Mayfield, Think Java, 2nd edition (Green Tea Press / O'Reilly, 2020) — Think Java 2e, Chapter 2 (Variables and Operators), Sections 2.1-2.5, pp. 17-23 — Chapter 2 opens on printed page 17.
Section
Section 2.1
Concept
A variable is a named location in memory that stores a value. To store a value you first have to declare the variable, which means saying what kind of values it may hold and what it is called.
String message;
int x;
String firstName;
String lastName;
int hour, minute;| declaration | type | name(s) |
|---|---|---|
| String message; | String | message |
| int x; | int | x |
| String firstName; | String | firstName |
| int hour, minute; | int | hour and minute — two at once |
variable — A named location in memory that stores a value.
declaration — A statement that creates a variable and gives it a type.
type — What kind of values a variable can store — int for integers like 1 and -5, char for characters like 'A' and 'z', String for text.
The last line shows how to declare several variables of the same type at once. Each declaration statement ends with a semicolon.
Notation
Every declaration you will write for the rest of this book has this shape. Naming the parts now means never having to guess later.
Annotate
int and char are lowercase; String is capitalised. You will learn why later, but take care to get it right now — there is no such type as Int or string.firstName is better than x everywhere except a throwaway example.Hello. When a name contains more than one word, capitalise each subsequent word: firstName.firstName, firstname and FirstName are three different variables, and mixing them up produces a 'cannot find symbol' error.public, class, static, void, int and others. These are keywords, and you cannot use them as variable names.You do not have to memorise the keyword list. Your editor colours them differently, and the compiler will complain if one sneaks past you both.
Worked example
You are writing a program that records a student's name and the score they got on a test out of 100. Decide the declarations before writing anything else.
String studentName;
int score;| what you are storing | type | why that type |
|---|---|---|
| a person's name | String | text — a sequence of characters |
| a whole-number score | int | scores out of 100 are integers; no decimal places needed |
Ask what kind of value each thing is.
Why: A name is text; a score is a whole number. The kind of value chooses the type.
Pick names that say what they mean.
Why: studentName and score — not s and n, which will be meaningless in a week.
Follow the conventions: lowercase first letter, capital for each later word.
Why: studentName, not StudentName (that looks like a class) and not studentname (harder to read).
Check that neither name is a keyword.
Why: Neither is. If you had wanted to call something class or int, the compiler would refuse.
End each declaration with a semicolon.
Why: A declaration is a statement, and statements end with semicolons.
Verify: Compile a program containing just these two declarations; it should compile cleanly and do nothing.
Why: If you get 'cannot find symbol', check the capitalisation of String — it is the one type here that takes a capital letter.
Definition probe
Apply the naming rules: no keywords, and the conventions for capitalisation.
Sort into buckets
Sort each proposed variable name.
Concept
Some languages let you write x = 5 with no type at all. Java makes you say int x = 5. The extra word is doing real work.
| because the type is written down | Java can... |
|---|---|
| it knows message holds text | reject message = 123; at compile time, before the program ever runs |
| it knows hour holds an integer | choose integer arithmetic for hour * 60 |
| it knows exactly how much room is needed | reserve the right amount of memory for the box |
| it knows what operations make sense | allow hour - 1 but reject subtracting one name from another |
The theme to notice: the type lets errors be caught by the compiler rather than by a user. That is the trade Java is making, and it is why the language feels wordy at first and reassuring later.
Trap
What gets typed by someone who has not yet noticed the pattern.
string message;
Int hour;
INT minute;| written | what Java looks for | result |
|---|---|---|
| string | a type named string | cannot find symbol — no such type |
| Int | a type named Int | cannot find symbol — no such type |
| INT | a type named INT | cannot find symbol — no such type |
All three produce the same unhelpful message. Java is not correcting your capitalisation; it is looking for a type with that exact name and finding nothing.
The correct forms, and the pattern behind them.
String message;
int hour;
char initial;
double ratio;| type | capitalised? | the pattern |
|---|---|---|
| int | no | a built-in primitive type |
| char | no | a built-in primitive type |
| double | no | a built-in primitive type |
| String | yes | a class from the Java library |
The pattern will make full sense in Chapter 9: lowercase types are primitives built into the language, and capitalised ones are classes. For now, the rule 'String is the odd one out' is enough.
Prediction
Read the punctuation carefully.
int hour, minute;
String firstName;| statement | variables created |
|---|---|
| int hour, minute; | two — hour and minute, both int |
| String firstName; | one |
Predict first
How many variables exist after these two statements?
Correct: Three
Why: The first statement declares two variables of the same type by separating the names with a comma, and the second declares one more — three in total. The comma form is a convenience for same-typed variables; the type is written once and applies to every name in the list.
Matching
Three of the types named in Section 2.1.
Match the pairs
Why: int stores integers like 1 and -5; char stores a single character in single quotes; String stores text in double quotes. The quotation marks are the tell — single quotes mean one character, double quotes mean a string, and no quotes at all means a number.
Socratic
It causes beginners real trouble. Ask whether the alternative would be better.
Discussion prompt
firstName and firstname are different variables. Suppose Java ignored case instead, so both names meant the same box. What would that make easier, and what would it make worse?
Hint: Think about a typo, and about whether you would want it to be silently accepted.
Answer:
It would make typos harmless — firstname would just work. But it would also make them invisible, and it would forbid you from ever having two variables whose names differed only in case.
The deeper reason is consistency: Java is case-sensitive everywhere — System and system, main and Main, String and string. One rule applied uniformly is easier to hold in your head than a rule with exceptions, even when the uniform rule is occasionally annoying.
Section
Section 2.2
Concept
Now that the variables exist, we can store values in them with an assignment statement. The idea is straightforward even though the vocabulary can be confusing.
message = "Hello!"; // give message the value "Hello!"
hour = 11; // assign the value 11 to hour
minute = 59; // set minute to 59| statement | the variable | its new value |
|---|---|---|
| message = "Hello!"; | message | "Hello!" |
| hour = 11; | hour | 11 |
| minute = 59; | minute | 59 |
The three comments show different ways people talk about the same operation — give, assign, set. They all mean the same thing.
Picture it
Watch one box over three statements.
Figure (svg): A trace strip showing a variable being declared with no value, then assigned 11, then re-assigned 12
The third step is the one to notice: assigning a new value replaces the old one. There is no history in the box — only whatever was put there most recently.
Worked example
You can declare a variable and assign it a value later, as in the example above. You can also do both on the same line, which is what you will normally want.
String message = "Hello!";
int hour = 11;
int minute = 59;| this one line | does the work of |
|---|---|
| String message = "Hello!"; | String message; then message = "Hello!"; |
| int hour = 11; | int hour; then hour = 11; |
| int minute = 59; | int minute; then minute = 59; |
Write the type and name as usual.
Why: That part is the declaration, unchanged.
Add = and the value before the semicolon.
Why: That part is the assignment, folded into the same statement.
Prefer this form when you know the value already.
Why: It makes it impossible to forget to initialise, which is a real compile error.
Verify: Print each variable and confirm you get Hello!, 11 and 59.
Why: Then try removing one of the initialisers and using that variable — the compiler will refuse, saying the variable may not have been initialised. That refusal is a feature.
Variables must be initialised — assigned for the first time — before they can be used.
Discrimination
Three kinds of statement, distinguished by whether a type appears and whether a value does.
Sort into buckets
Sort each statement.
Concept
As a general rule, a variable has to have the same type as the value you assign to it. You cannot store a string in minute or an integer in message.
Figure (svg): A rule card showing that assigning the string 123 to a String is legal but assigning the integer 123 is not
| assignment | legal? | why |
|---|---|---|
| String message = "123"; | yes | a String variable, given a string |
| String message = 123; | no | a String variable, given an integer |
| int minute = 59; | yes | an int variable, given an integer |
| int minute = "59"; | no | an int variable, given a string |
Some strings look like integers but are not. "123" is made up of the characters '1', '2' and '3'; the integer 123 is a number you can do arithmetic with. Chapter 3 shows how to convert between them.
Trap
Declared, but never given a value — and then used.
int hour;
System.out.println(hour);| statement | state of hour | result |
|---|---|---|
| int hour; | declared, no value | fine so far |
| println(hour); | still no value | compile error: variable hour might not have been initialized |
Note that this is a compile-time error, not a crash at run time. Java refuses to build a program that could read an empty box.
Initialise before use — ideally on the declaration line itself.
int hour = 11;
System.out.println(hour);| statement | state of hour | result |
|---|---|---|
| int hour = 11; | declared and initialised to 11 | fine |
| println(hour); | 11 | displays 11 |
Declaring and initialising on one line makes this error impossible to commit. That is a good reason to prefer it whenever you already know the value.
Prediction
One assignment breaks the type rule.
String a = "123";
int b = 123;
String c = 123;
int d = 59;| statement | variable type | value type |
|---|---|---|
| String a = "123"; | String | string — matches |
| int b = 123; | int | integer — matches |
| String c = 123; | String | integer — does NOT match |
| int d = 59; | int | integer — matches |
Predict first
Which line is a compile error?
Correct: String c = 123;
Why: A String variable cannot be given an integer value. The first line is fine because "123" in quotes is a string that happens to look numeric — it is the three characters 1, 2 and 3, not the number. The quotation marks are what decide the type, not the characters inside them.
Fill the middle
Rewrite a declaration and an assignment as a single statement.
Fill in the blanks
// was: int score; then score = 87;
int score = 87;
Why: The type goes at the front and the assignment operator joins the name to its initial value: int score = 87;. This single statement declares the variable and initialises it, which is both shorter and safer than the two-statement form.
Counterexample
You have just been told to prefer the one-line form. Push back on it.
Discussion prompt
If declaring and initialising together prevents a whole class of error, why does Java allow you to declare a variable without giving it a value at all? Try to think of a situation where you would have to.
Hint: What if the value depends on something the program has not worked out yet?
Answer:
Because sometimes the value is not known at the point where the variable has to exist. You will meet this properly in Chapter 5: a variable declared before an if statement, and given one value or another depending on which branch runs.
So the guidance is not 'always initialise on the declaration line' — it is 'initialise as soon as you know the value'. Java's compile-time check means you cannot get this wrong silently, which is why the language can afford to allow the split form at all.
Section
Section 2.3
Concept
Because Java uses the = symbol for assignment, it is tempting to read a = b as a statement of equality. It is not. Two properties of mathematical equality fail here.
Figure (svg): A rule card contrasting mathematical equality, which is commutative and permanent, with Java assignment which is neither
| property of equality | in mathematics | in Java assignment |
|---|---|---|
| commutative | if a = 7 then 7 = a | a = 7; is legal, 7 = a; is not |
| permanent | if a = b now, always | a and b can be made equal and then diverge |
| what may go on the left | any expression | a variable name — a storage location — only |
Read a = 7 as a command — put 7 into a — rather than as a claim. That reading is correct, and it makes every later assignment obvious.
Picture it
Three statements. After the second, a and b hold the same value; after the third, they do not — and nothing touched b.
Figure (svg): A memory diagram showing variable a holding 3 and variable b holding 5 after a was reassigned
int a = 5; int b = a; a = 3; — the third line changes a, but it does not change b. The assignment b = a copied the value 5 at that moment; it did not tie the two boxes together.
Worked example
This is the technique you will use for the rest of the book: keep a table of every variable and update it one statement at a time.
int a = 5;
int b = a;
a = 3;
int c = 0;| after this statement | a | b | c |
|---|---|---|---|
| int a = 5; | 5 | — | — |
| int b = a; | 5 | 5 | — |
| a = 3; | 3 | 5 | — |
| int c = 0; | 3 | 5 | 0 |
Give every variable a column as it is declared.
Why: A dash means the variable does not exist yet.
For int b = a;, look up a's CURRENT value and copy it.
Why: a is 5, so b becomes 5. The link between them ends there.
For a = 3;, change only a's column.
Why: Nothing else on the row changes, because nothing else was assigned.
Read the final row as the memory diagram.
Why: a is 3, b is 5, c is 0 — three boxes, three values.
Verify: Print all three and expect 3, 5, 0.
Why: If you predicted b would be 3, you read b = a as a permanent link rather than a one-time copy — which is exactly the misconception this section exists to break.
Prediction
Trace it with a table before answering.
int x = 10;
int y = x;
x = 20;
y = y + 1;
System.out.println(x + " " + y);| after | x | y |
|---|---|---|
| int x = 10; | 10 | — |
| int y = x; | 10 | 10 |
| x = 20; | 20 | 10 |
| y = y + 1; | 20 | 11 |
Predict first
What is displayed?
Correct: 20 11
Why: y was given a copy of x's value (10) and then had 1 added to it, giving 11. Reassigning x to 20 later does not affect y at all, because the copy was made once, at the moment int y = x; ran. The last line reads the current contents of both boxes: 20 and 11.
Concept
Taken together, the variables in a program and their current values make up the program's state. A memory diagram shows the state at one particular point in time.
Figure (svg): A memory diagram of three variables a, b and c holding 3, 5 and 0
state — The variables in a program together with their current values.
memory diagram — A drawing of the state: each variable is a box with its name outside and its current value inside.
As the program runs the state changes, so a diagram is a snapshot, not a summary. When you draw one, always write down which statement you drew it after — a diagram with no timestamp cannot be checked.
Trap
The misconception. b = a makes b follow a, so changing a changes b too.
int a = 5;
int b = a;
a = 3;
System.out.println(b); // predicted: 3| statement | what the misconception predicts | what really happens |
|---|---|---|
| int b = a; | b is now linked to a | b is given a copy of a's current value, 5 |
| a = 3; | b follows and becomes 3 | only a changes |
| println(b); | prints 3 | prints 5 |
This misreading comes straight from mathematics, where an equation states a relationship that holds for all time. Java's = states nothing; it does something, once.
Assignment copies a value, at the moment it runs.
int a = 5;
int b = a; // b gets a COPY of 5
a = 3; // only a changes
System.out.println(b); // 5| after | a | b |
|---|---|---|
| int a = 5; | 5 | — |
| int b = a; | 5 | 5 |
| a = 3; | 3 | 5 |
Say it as a command: put a copy of what is currently in a into b. Nothing about that sentence suggests a lasting connection — which is why the command reading is the useful one.
Error analysis
A student annotated their own trace of the fragment below. One annotation is right and three are wrong.
Annotate
int b = a; creates b and gives it a value in one statement.3 is not a location.Three of the four errors come from reading = as equality. That single misreading is responsible for most confusion in this chapter.
Two truths and a lie
Four claims about the = operator.
Eliminate the wrong options
Eliminate the false claims and keep the true one.
Survives elimination: B
Why: The left side of an assignment names the storage location being written to, so it has to be a variable. Every other claim here comes from importing a property of mathematical equality — commutativity or permanence — that assignment simply does not have.
Explain it to yourself
One sentence, in your own words.
Discussion prompt
Explain what a memory diagram shows and — more importantly — what it deliberately does not show. Why does that limitation matter when you use one to find a bug?
Hint: Think about time.
Answer:
It shows the state: every variable that exists, and the value in each, at one moment. It does not show how the state got there, and it does not show what happens next.
That limitation is exactly what makes it useful for debugging. A bug is a moment where the state stops matching what you expected, and finding it means comparing snapshots statement by statement until the first mismatch. A diagram without a 'this is after line 3' label cannot be compared to anything.
Section
Section 2.4
Concept
You can display the current value of a variable with print or println. When we talk about displaying a variable, we generally mean the value of the variable. To display the name, you have to put it in quotes.
String firstLine = "Hello, again!";
System.out.print("The value of firstLine is ");
System.out.println(firstLine);| what is printed | in quotes? | what appears |
|---|---|---|
| "The value of firstLine is " | yes | the words themselves |
| firstLine | no | the value: Hello, again! |
The output is: The value of firstLine is Hello, again! — quotes mean literal text, no quotes means look up the variable and print what is inside.
Picture it
One decision, made every time you print. It is the same code-versus-data distinction from Lesson 1b, wearing different clothes.
Figure (svg): Two boxes contrasting printing text in quotes with printing a variable without quotes
Two statements that differ by two characters and produce completely different output. When printed text looks like a variable name, this is always the cause.
Worked example
Conveniently, the code for displaying a variable is the same regardless of its type. Build a line of output from literal text and two int variables.
int hour = 11;
int minute = 59;
System.out.print("The current time is ");
System.out.print(hour);
System.out.print(":");
System.out.print(minute);
System.out.println(".");| statement | quoted? | output so far |
|---|---|---|
| print("The current time is ") | yes | The current time is |
| print(hour) | no | The current time is 11 |
| print(":") | yes | The current time is 11: |
| print(minute) | no | The current time is 11:59 |
| println(".") | yes | The current time is 11:59. |
Alternate quoted text and unquoted variables.
Why: Literal punctuation like the colon goes in quotes; values do not.
Use print for everything but the last piece.
Why: Otherwise each piece lands on its own line.
Finish with println.
Why: And do not forget it — see the warning below.
Verify: Run it and expect exactly one line: The current time is 11:59.
Why: If nothing appeared at all, you left off the final println — which is a real hazard, not a hypothetical one.
Prediction
Watch the quotation marks.
int score = 87;
System.out.print("score");
System.out.print(" = ");
System.out.println(score);| argument | quoted? | output |
|---|---|---|
| "score" | yes | score |
| " = " | yes | = |
| score | no | 87 |
Predict first
What appears on the screen?
Correct: score = 87
Why: The first argument is quoted so the word 'score' is printed literally; the third is unquoted so Java looks up the variable and prints 87. This pattern — a quoted label followed by an unquoted value — is how nearly every piece of labelled output in this book is written.
Concept
Think Java gives an unusually specific warning here, and it is worth taking seriously because the symptom is so confusing.
Figure (svg): A rule card warning that output from print may be buffered and only displayed when println runs
| what you wrote | what you might see |
|---|---|
| several prints, ending with println | the line, as expected |
| several prints, no println | nothing — until something else ends the line |
| several prints, no println, program ends | possibly nothing at all |
On many computers the output from print is stored without being displayed until println runs; then the entire line is displayed at once. If you omit the println, the program might display the stored output at unexpected times, or even terminate without displaying anything.
Trap
Quotes around everything, on the theory that print needs them.
int hour = 11;
System.out.print("The hour is ");
System.out.println("hour");| statement | read as | output |
|---|---|---|
| print("The hour is ") | literal text | The hour is |
| println("hour") | literal text | hour |
Output: The hour is hour. No error, no warning — just the wrong thing, every time.
Quotes only around the literal text.
int hour = 11;
System.out.print("The hour is ");
System.out.println(hour);| statement | read as | output |
|---|---|---|
| print("The hour is ") | literal text | The hour is |
| println(hour) | the variable — look up its value | 11 |
Output: The hour is 11. The rule is unchanged from Lesson 1b — inside quotes is data, outside quotes is code — and here 'code' means 'a variable to look up'.
Fill the middle
Produce the output: minutes: 59
Fill in the blanks
int minute = 59;
System.out.print("minutes: ");
System.out.println(minute);
Why: The label is literal text and needs quotation marks, including the trailing space that separates it from the number. The value is the variable itself with no quotes, so Java looks it up. Quoting the second one would print the word 'minute' instead of 59.
Hypothesis
A student's program runs, exits normally, and displays nothing at all. The code is three print calls with no println.
Predict first
What is the most likely explanation?
Correct: The output was stored waiting for a newline, and the program ended before it was displayed
Why: On many computers output from print is buffered — stored without being displayed — until a println flushes the line. A program that only ever calls print can therefore terminate with its output still waiting. This is exactly why Think Java says 'don't forget the println', and why the symptom is no output rather than wrong output.
Explain it
The rule is short; the explanation of why is what makes it stick.
Discussion prompt
A classmate wrote System.out.println("total"); and cannot understand why it printed the word 'total' rather than the number in their total variable. Explain the rule and, more importantly, explain why Java cannot simply work out what they meant.
Hint: What would happen if Java tried to guess?
Answer:
The rule: quotes mean this exact text; no quotes means look up this name and print what is in it.
Java cannot guess, because both are things people genuinely want. Printing the literal word 'total' as a label is just as common as printing the value — in fact the usual line does both: print("total: "); println(total);. If Java tried to be helpful, there would be no way left to print a label that happens to share a name with a variable.
Section
Section 2.5
Concept
Operators are symbols that represent simple computations: + for addition, - for subtraction, * for multiplication and / for division. An expression is a combination of numbers, variables and operators that represents a single value to be computed.
int hour = 11;
int minute = 59;
System.out.print("Number of minutes since midnight: ");
System.out.println(hour * 60 + minute);| step | the expression |
|---|---|
| as written | hour * 60 + minute |
| replace each variable with its value | 11 * 60 + 59 |
| multiplication happens first | 660 + 59 |
| then the addition | 719 |
operator — A symbol that represents a simple computation, such as + or *.
expression — A combination of numbers, variables and operators that computes to a single value.
operand — A value that an operator works with.
When the program runs, each variable is replaced by its current value, and then the operators are applied. That two-step reading is how you evaluate any expression by hand.
Picture it
Multiplication before addition, exactly as in arithmetic. The useful habit is to write each intermediate form down rather than doing it all in your head.
Figure (svg): A trace strip reducing the expression hour times 60 plus minute to 719 in three steps
Every expression in this book can be reduced this way. When one surprises you, write the steps out — the surprise is almost always at a single step you can then point at.
Worked example
This fragment tries to compute the fraction of an hour that has passed. It is correct Java, it compiles cleanly, and the answer is wrong.
int minute = 59;
System.out.print("Fraction of the hour that has passed: ");
System.out.println(minute / 60);| step | value | note |
|---|---|---|
| minute / 60 | 59 / 60 | both operands are integers |
| exact answer | 0.98333... | but this is not what Java computes |
| integer division | 0 | rounds toward zero |
| displayed | 0 | correct Java, wrong answer |
Notice the types of both operands.
Why: minute is an int and 60 is an int. Both integers.
Java therefore performs integer division.
Why: By design, integer division always rounds toward zero — even when the next integer is very close.
Accept that 59 / 60 is 0.
Why: Not a bug and not a rounding accident. It is the defined behaviour of / on two integers.
Work around it by scaling first.
Why: minute * 100 / 60 multiplies before dividing, so the division has something to work with.
Verify: Change the statement to System.out.println(minute * 100 / 60); and expect 98.
Why: Again the result is rounded down, but at least now it is approximately correct. Section 2.6 gives the general fix — floating-point numbers.
Prediction
Both operands are integers.
System.out.println(7 / 2);| operands | kind of division | result |
|---|---|---|
| 7 and 2, both int | integer division | 3 |
| exact value | — | 3.5 |
| what happened to the .5 | discarded — rounds toward zero | — |
Predict first
What is displayed?
Correct: 3
Why: Both operands are integers, so Java performs integer division and rounds toward zero, discarding the 0.5. Note that it rounds toward zero rather than to the nearest integer — 7/2 is 3, and it would still be 3 if the exact answer were 3.9.
Concept
minute * 100 / 60 gives 98, but minute / 60 * 100 gives 0. In ordinary arithmetic these are the same quantity. With integer division they are not, because information is discarded at each division.
| expression | evaluated left to right | result |
|---|---|---|
| minute * 100 / 60 | 59 * 100 = 5900, then 5900 / 60 | 98 |
| minute / 60 * 100 | 59 / 60 = 0, then 0 * 100 | 0 |
| (the exact value) | 59 / 60 = 0.98333... | 98.33... |
The rule to take away: with integer division, multiply before you divide. Each division throws away the remainder, so doing one early destroys precision that later steps cannot recover.
Trap
The expectation. Division means division, so this should be about 0.98.
int minute = 59;
System.out.println(minute / 60); // expected 0.98333| operand | type |
|---|---|
| minute | int |
| 60 | int |
| therefore / | integer division — rounds toward zero |
The output is 0. Nothing warns you, because nothing is wrong as far as Java is concerned — you asked for integer division and you got it.
The rule. Java performs integer division when both operands are integers, and integer division always rounds toward zero.
int minute = 59;
System.out.println(minute * 100 / 60); // 98 — scale up first
// or, from Section 2.6:
// double m = 59.0; System.out.println(m / 60.0); // 0.9833...| approach | operands | result |
|---|---|---|
| minute / 60 | int, int | 0 |
| minute * 100 / 60 | int, int — but scaled first | 98 |
| 59.0 / 60.0 | double, double | 0.9833333333333333 |
Two fixes, and they solve different problems. Scaling keeps integers and gives you a percentage; switching to double gives you the fraction itself. The next lesson takes up the second one.
Ranking
For the expression hour * 60 + minute with hour = 11 and minute = 59.
Put in order
Why: Java replaces each variable with its current value first, then applies the operators in precedence order — multiplication before addition. Writing the intermediate forms out is the technique that turns a surprising result into a step you can point at.
Estimation
All four use only integers. Only one gives the percentage.
Predict first
With minute = 59, which expression evaluates to 98?
Correct: minute * 100 / 60
Why: Multiplying before dividing keeps the precision: 59 * 100 is 5900, and 5900 / 60 is 98. Any version that divides first destroys the information — 59 / 60 is 0 and 100 / 60 is 1, so the other three give 0, 0 and 59 respectively. With integer division, multiply before you divide.
Edge cases
You have seen it round down. Find the cases where it does not lose anything.
Discussion prompt
Integer division discards a remainder. For which pairs of integers does it discard nothing, so the result is exactly right? And is 'rounds toward zero' the same as 'rounds down' for every pair you can think of?
Hint: Try a negative numerator for the second half.
Answer:
It is exact whenever the numerator is a multiple of the denominator: 6 / 3 is exactly 2, 100 / 25 is exactly 4. There is no remainder to discard.
And no — 'toward zero' and 'down' differ for negatives. -7 / 2 is -3, not -4: rounding toward zero moves a negative result up. Think Java's phrasing, 'always rounds toward zero', is deliberately precise for exactly this reason.
Chapter 3 introduces the remainder operator %, which hands you the part that integer division threw away — and the two together let you recover the exact answer.
Comparison
Three new things this lesson added. Fill the blanks to keep them apart.
Comparison matrix
| declaration | assignment | expression | |
|---|---|---|---|
| example | int hour; | hour = 11; | hour * 60 + minute |
| what it does | creates a named storage location | updates the value in one | computes a single value |
| has a type? | yes — you write it | no — the variable already has one | yes — decided by its operands |
| is a statement? | yes, ends with a semicolon | yes, ends with a semicolon | no — it is part of one |
The last row is the one that catches people: an expression is not a statement. hour * 60 on its own line is not a legal program — it computes a value and then does nothing with it.
Pattern
Two habits from this lesson do more work than anything else: read = as a command, and evaluate expressions by substitution.
| when you see | read it as | not as |
|---|---|---|
| int x = 5; | make a box called x and put 5 in it | x equals 5, forever |
| b = a; | copy what is in a into b, now | link b to a |
| hour * 60 + minute | substitute values, then apply operators | a formula to admire |
| 59 / 60 | integer division — rounds toward zero | 0.98333 |
=; initialise before use.Check
Work it out before you click.
int p = 4;
int q = p;
p = p + 1;
q = q + p;| after | p | q |
|---|---|---|
| int p = 4; | 4 | — |
| int q = p; | 4 | 4 |
| p = p + 1; | 5 | 4 |
| q = q + p; | 5 | 9 |
Check your understanding
What are the final values of p and q?
Answer: A
Why: q gets a copy of 4, then p becomes 5, then q becomes its own value (4) plus p's current value (5), which is 9. The key step is that changing p after the copy does not retroactively change q, but a later statement reading p does see the new value.
p = p + 1; actually changes p — the right side is evaluated first, then stored back.Check
Work it out before you click.
Check your understanding
With int total = 7; what does System.out.println(total / 2 * 2); display?
Answer: A
Why: Evaluation is left to right for operators of equal precedence: 7 / 2 is 3 by integer division, and 3 * 2 is 6. The remainder discarded by the division is gone for good, so multiplying back by 2 does not recover the original 7 — which is a compact demonstration of why you should multiply before dividing.
Check
Work it out before you click.
int n = 5;
System.out.println("n" + " = " + n);| piece | quoted? | contributes |
|---|---|---|
| "n" | yes | the letter n |
| " = " | yes | = |
| n | no | the value 5 |
Check your understanding
What does this display?
Answer: A
Why: The first two pieces are in quotation marks and print literally, while the third is the bare variable name, so Java looks it up and prints 5. The spaces around the equals sign are inside the quotes, so they appear in the output exactly as typed.
Real world
This is not a beginner's trap that you outgrow. Integer division causes real bugs in shipped software, and the reason is always the same.
Discussion prompt
Think of somewhere a program divides one whole number by another — splitting a bill, working out a percentage, paging through search results. Where could rounding toward zero cause a visible bug, and who would notice?
Hint: Think about 'showing results 1 to 10 of 95'.
Answer:
Pagination is the classic case: 95 results at 10 per page is 95 / 10, which is 9 — and the last five results become unreachable. The fix is (95 + 9) / 10, and getting it wrong is a bug users hit rather than a bug tests catch.
Splitting money is the other one. Dividing 100 pence three ways gives 33 each and loses a penny, which is why financial code tracks the remainder explicitly rather than pretending it does not exist.
The transferable habit: whenever you write / between two integers, ask what happens to the remainder. Sometimes discarding it is exactly right. The bug is not the rounding — it is not having decided.
Commit first
Commit to an answer and to your confidence in it.
Predict first
After int a = 5; int b = a; a = 3; what is the value of b?
Correct: 5
Why: b was given a copy of a's value at the moment int b = a; ran, and that value was 5. Reassigning a afterwards changes only a — the two variables are separate boxes, and the assignment created no lasting link between them. If you were confident the answer was 3, you are reading = as mathematical equality, which is the single most useful misconception to have corrected in this chapter.
Explain it
Two minutes, out loud, no slides.
Discussion prompt
Explain to someone who knows algebra but not programming why a = a + 1; is a perfectly sensible statement in Java, even though it is nonsense as an equation. Then explain why 7 = a; is not allowed.
Hint: The word to reach for is 'command'.
Answer:
In algebra a = a + 1 has no solution. In Java it is not a claim at all — it is an instruction: take what is currently in a, add one to it, and put the result back in a. Read right to left, it is completely reasonable.
And 7 = a; is not allowed because the left side names where to put the value. a is a box; 7 is not a box, so there is nowhere for the value to go.
If you found yourself saying 'equals' out loud, try 'gets' or 'becomes' instead — a gets a + 1. Changing the word you use is the fastest way to change the reading.
Exit ticket
One question before you close the deck.
Predict first
Why does System.out.println(59 / 60); display 0 rather than 0.98333?
Correct: Both operands are integers, so Java performs integer division, which rounds toward zero
Why: The types of the operands decide which division is performed. Two ints mean integer division, and integer division discards the remainder rather than rounding to the nearest value. Java can represent 0.98333 perfectly well — that is what double is for, and it is the subject of the next lesson — but nothing in this expression asked for it.
Connect it up
One page, from memory.
Draw it
Draw the memory diagram after each of these four statements, four diagrams in a row: int a = 5; int b = a; a = 3; int c = a * 60 + b;. Label each diagram with the statement it follows. Then, underneath, write the value of b / a and the value of b * 100 / a, and one sentence saying why they are not simply 100 times apart.
Recap
Five sections that between them turn a program from something that prints fixed text into something that can hold a value and compute with it.
| if you remember one thing | it is this |
|---|---|
| about assignment | read = as 'gets', never as 'equals' |
| about tracing | one column per variable, one row per statement |
| about arithmetic | two ints divided give an int |
int, char and double are lowercase, String is capitalised, and a value must match its variable's type.= copies a value into a storage location, once.Want this taught 1-on-1? Alexander tutors Java — $55/session, free consultation.