Where your objects actually live — between new and the last println.
In Lab 1 you created three Book objects and never once asked WHERE they were. Today you get the full map: the stack that holds your method calls, the heap that holds your objects, the one shared copy that static creates, what a parameter REALLY carries, when the garbage collector finally lets go — and the one keyword that makes a value permanent.
The hook, before anything else: in Lab 1's Exercise 3 you wrote Book[] shelf = new Book[3]; and the run just… worked. But three different regions of memory cooperated to make those 12 output lines appear — and if you can name them, you can predict every weird Java behaviour from now until Unit 5. This class is the map.
PART 2 · WHAT TODAY DELIVERS
Four skills. Ten stops. One map of memory.
final method + final class OUT to Class 10, because "cannot be overridden / cannot be extended" mean nothing until extends is taught. What stays here is complete without inheritance: the final CONSTANT.
BY THE END YOU CAN
- Explainwhy a method can never change a number you pass it — yet CAN empty your tiffin box — and why two variables often turn out to be one object (aliasing).
- Predictthe value of a
staticcounter after any sequence ofnewcalls — without running it. - Traceany variable to its true address: stack frame, heap object, or the class's shared shelf.
- Classifyany field as static / instance /
finalconstant — the exam's favourite 2-mark sorting task.
WHERE THIS SITS
TODAY'S ROUTE · 10 STOPS
- The copy rule — 8 micro-programs · numbers, slips, one shared boxSIM
static— one copy, owned by the classCODE- Initializer blocks — static & instanceSELF-STUDY
- Stack vs heap — the full memory mapSIM
- Activity 1 — predict the static counterNOTEBOOK
- Activity 2 — static or instance? classify 6NOTEBOOK
- Garbage collection — when Java lets goSIM
- GC generations — why the sweep sorts by ageSELF-STUDY
final— a value decided once, foreverPYQ FEED- Activity 3 — design a real constantNOTEBOOK
CLASS 09 OF 60 · 15 PAGES · 12 PARTS · 8 MICRO-PROGRAMS · FEEDS CLASS 10
PART 3 · THE COPY RULE
Eight tiny programs. One rule:
Java always copies.
There is NO big program anywhere in this part. Instead: eight micro-programs, none longer than 15 lines, each answering exactly ONE small question — and each acted out first as an everyday story: pocket money, a phone recharge, unfinished homework, a shared tiffin box, a painted room, a new-box trick. If you can follow "my friend copied my number into his notebook", you can follow all eight. The exam calls today's rule pass-by-value; the everyday version is one line: Java always copies — the only question is: copies WHAT?
How to use this part — three moves, every single time: ① read the little story, ② say your guess OUT LOUD (one number or one word — that is all any program here prints), ③ press, and watch the terminal agree with you. If a program ever surprises you, the story sitting right beside it is the answer key — re-read it and press again. Nothing below needs anything beyond Class 8: a tiny class, a field, new, and println. And every idea is shown by MORE THAN ONE example on purpose — if the tiffin box doesn't click for you, the painted room will.
MICRO-STORY 1 · NO CODE · THE POCKET-MONEY NOTEBOOK — ONE PIECE PER PRESS
Copying a NUMBER makes two independent numbers. Once copied, the two pages have nothing to do with each other — that is the entire story. ✓
Now that exact story as ten lines of Java — every single line is Class-2 material.
MICRO 1 OF 8 · PocketMoney.java — YOU DO THE COPYING YOURSELF · NOTHING NEW HERE
- Save as
PocketMoney.javainclass-09\ - In
main:int mine = 500;, then copy it —int friend = mine; - Add 100 to
friendonly, then printmineandfriend(one per line)
500 then 600 — your page untouched, his page +100.public class PocketMoney{ public static void main(String[] args) { int mine = 500; // your notebook page int friend = mine; // friend copies the NUMBER — two pages now friend = friend + 100; // he scribbles on HIS page System.out.println(mine); // your page? System.out.println(friend); // his page? }}C:\Users\diya\Desktop\java-practice\class-09> javac PocketMoney.java
C:\Users\diya\Desktop\java-practice\class-09> java PocketMoney
500
600
You said 500 and 600 before pressing — of course you did. Line 6 copied the number onto a second page; line 7 scribbled on that second page. Your page never moved. Keep that feeling of "obviously": every program in this part wants the same feeling.
int and assignment from Class 2, arithmetic from Class 3, printlns from day one. Micro 1 exists to prove the notebook story is something you ALREADY believe about Java.Micro 2 — the SAME story, one change: in PocketMoney, you wrote the copy line (int friend = mine;). Now we hand the number to a method instead — and Java writes that very same copy line for us, invisibly, at the moment of the call. A method parameter IS int friend = mine; in disguise — a fresh notebook page that Java fills in for you. That is the ONLY new idea. One word to disarm before you read it — static: the helper is written static void …, and that word has NOT been taught yet. Don't let it worry you — you have typed it in every program since Class 2: public static void main. For today it means only: "this method belongs to the file itself, so main can call it directly, without creating any object first." It gets its own gentle introduction in Part 4.
MICRO 2 OF 8 · Recharge.java — NOW JAVA WRITES THE COPY LINE FOR YOU
- Save as
Recharge.javainclass-09\ - Write
static void topUp(int balance)that adds 100 to its parameter - In
main:int myBalance = 40;, calltopUp(myBalance);, then printmyBalance
40 — the method only ever scribbled on its own copy.public class Recharge{ static void topUp(int balance) // = "int balance = myBalance;" in disguise { balance = balance + 100; // adds ₹100 to the COPY } public static void main(String[] args) { int myBalance = 40; topUp(myBalance); System.out.println(myBalance); }}C:\Users\diya\Desktop\java-practice\class-09> javac Recharge.java
C:\Users\diya\Desktop\java-practice\class-09> java Recharge
40
Still 40! Line 10 handed topUp a COPY of the number 40 — a fresh page. Line 5 added 100 to that copy; then the method ended and its page was thrown away. main's own 40 never moved. Feels wrong for a second — then you remember the notebook: the friend scribbled on HIS page.
int friend = mine;). Micro 2's copy line is invisible — Java writes it when the call happens. Two programs, one rule: numbers get copied.MICRO 3 OF 8 · Homework.java — SAME IDEA, THIRD EXAMPLE · THIS TIME YOU CALL IT BEFORE READING THE ANSWER
- Save as
Homework.javainclass-09\ - Write
static void finishAll(int pending)that setspending = 0; - In
main:int pendingSubjects = 5;, callfinishAll(pendingSubjects);, print it - Say your answer OUT LOUD before compiling
5 — no method can finish your homework on a copy.public class Homework{ static void finishAll(int pending) { pending = 0; // "done!" … on the copy } public static void main(String[] args) { int pendingSubjects = 5; finishAll(pendingSubjects); System.out.println(pendingSubjects); }}C:\Users\diya\Desktop\java-practice\class-09> javac Homework.java
C:\Users\diya\Desktop\java-practice\class-09> java Homework
5
Still 5 — sadly, no method can finish your homework by writing 0 on its own copy. If you called this one BEFORE the terminal confirmed it, the number half of the rule is yours: hand a method a number, and it only ever gets a copy of that number.
Half-time — the number half is done. Now, objects — and ONE new picture: in a hostel, your tiffin box does not sit in your pocket; it sits in the common fridge, and what you carry is a small slip of paper — "my box is #7". That is EXACTLY how Java stores objects (Class 8 said it once; today it earns its keep): a variable like TiffinBox mine does NOT hold the box — it holds the slip with the box's number. The box itself lives elsewhere (a place Part 6 will name). One question drives the next three stories: if slips get copied like any other value… what happens to the ONE box they all point at? Watch it as a story first — one piece per press, no code yet.
MICRO-STORY 4 · NO CODE · ONE TIFFIN BOX, TWO SLIPS — ONE PIECE PER PRESS
Two slips · ONE box. Change the box through ANY slip, and EVERY slip-holder sees the change — because there is nothing else to see. ✓
That is the single most important picture in Class 9. Now the same story as 12 lines of Java — no method needed yet.
MICRO 4 OF 8 · TiffinShare.java — TWO NAMES, ONE BOX · NO METHOD, NOTHING HIDDEN
new. When the roommate eats through his name, what do YOU see through yours?- Save as
TiffinShare.javainclass-09\ - Tiny helper class:
class TiffinBox { int laddus = 4; } TiffinBox mine = new TiffinBox();thenTiffinBox roommate = mine;— NO secondnew- Roommate eats 3 (
roommate.laddus - 3), then printmine.laddusandroommate.laddus
1 and 1 — one box, two slips: that's aliasing.class TiffinBox { int laddus = 4; }public class TiffinShare{ public static void main(String[] args) { TiffinBox mine = new TiffinBox(); // ONE box in the fridge · your slip TiffinBox roommate = mine; // copies the SLIP — no new, no second box! roommate.laddus = roommate.laddus - 3; // he opens THE box and eats 3 System.out.println(mine.laddus); // YOUR slip — 4 or 1? System.out.println(roommate.laddus); }}C:\Users\diya\Desktop\java-practice\class-09> javac TiffinShare.java
C:\Users\diya\Desktop\java-practice\class-09> java TiffinShare
1
1
BOTH print 1 — because there was only ever ONE box. Count the news: one. Line 7 copied a slip, not a box. So when the roommate ate 3 laddus, he ate them out of YOUR box — the only box. Changing the object through one name changes what EVERY name sees. This has a name — aliasing: two (or more) variables that are just different names for the same one object.
news ran?" That many objects exist — no more, no matter how many variable names you see. Names are free; boxes cost a new.MICRO 5 OF 8 · TwoBoxes.java — THE OPPOSITE CASE, SO YOU CAN'T MIX THEM UP · TWO news = TWO BOXES
new box — and prove your laddus survive his lunch.- Save as
TwoBoxes.javainclass-09\ - Same
TiffinBoxhelper class (laddus = 4) - Line 7 is the change:
TiffinBox friend = new TiffinBox();— a SECONDnew - Friend eats 3 from HIS box, then print
mine.laddusandfriend.laddus
4 then 1 — two news, two boxes, no sharing.class TiffinBox { int laddus = 4; }public class TwoBoxes{ public static void main(String[] args) { TiffinBox mine = new TiffinBox(); // box 1 TiffinBox friend = new TiffinBox(); // a SECOND new — a second, separate box friend.laddus = friend.laddus - 3; // he eats from HIS OWN box System.out.println(mine.laddus); System.out.println(friend.laddus); }}C:\Users\diya\Desktop\java-practice\class-09> javac TwoBoxes.java
C:\Users\diya\Desktop\java-practice\class-09> java TwoBoxes
4
1
This time your laddus are safe — TWO news ran, so two boxes exist, and the friend ate from his own. Put Micro 4 and Micro 5 side by side: the ONLY difference is line 7 — = mine (share the box) versus = new TiffinBox() (get your own box). That one line is the whole objects story.
news. Done.Micro 6 — aliasing isn't limited to two names, and it isn't a trick — it's a feature: a family repaints their hall. The mother's phone note says "our hall", the father's says "the big room", the painter's job card says "flat 302 hall" — three pieces of paper, ONE room. When the painter finishes, does the mother need to be told her hall is blue now? No — she just looks: it's the same room. As many slips as you like can point at one object; a change made through ANY of them is instantly what ALL of them see. Watch three names share one room:
MICRO 6 OF 8 · PaintTeam.java — THREE NAMES, ONE ROOM · CHANGE IT ONCE, EVERYONE SEES BLUE
- Save as
PaintTeam.javainclass-09\ - Helper class:
class Room { String colour = "white"; } - ONE
new:Room hall = new Room();thencleaner = hall;andpainter = hall; - Set
painter.colour = "blue";then printhall.colourandcleaner.colour
blue and blue — one room, one truth, three names.class Room { String colour = "white"; }public class PaintTeam{ public static void main(String[] args) { Room hall = new Room(); // the ONE and only new Room cleaner = hall; // second slip, same room Room painter = hall; // third slip, same room painter.colour = "blue"; // painted ONCE, through one name System.out.println(hall.colour); System.out.println(cleaner.colour); }}C:\Users\diya\Desktop\java-practice\class-09> javac PaintTeam.java
C:\Users\diya\Desktop\java-practice\class-09> java PaintTeam
blue
blue
One new, one room. The paint went on through painter, and hall and cleaner see blue with zero extra work — there is no "old white copy" anywhere for them to see. Say the full sentence once: change an object through any one of its names, and every other name that points at that same object sees the change immediately.
Book[] shelf works because of this — the array slot and your loop variable can both point at the same Book, and an update through either is just… the truth. One object, one truth, many names.Micro 7 — now join the two halves: the first half said "a method receives a COPY". This half says "a copied slip opens the SAME box". Put them together: hand an OBJECT to a method, and the method receives a copy of the slip — which opens your real box. So a method CAN change your object's insides (it has the box number!) even though it can never change a number you pass. Same copy rule, different thing copied. Watch it — a roommate method, invited to lunch:
MICRO 7 OF 8 · LunchBreak.java — HAND A SLIP TO A METHOD · CAN IT REACH YOUR LADDUS?
- Save as
LunchBreak.javainclass-09\ - Same
TiffinBoxhelper class (laddus = 4) - Write
static void lunch(TiffinBox t)that eats 3:t.laddus = t.laddus - 3; - In
main: make ONE box, calllunch(mine);, printmine.laddus
1 — Recharge's 40 stayed 40, but a copied slip still opens YOUR box.class TiffinBox { int laddus = 4; }public class LunchBreak{ static void lunch(TiffinBox t) // t = a COPY of the slip — not of the box { t.laddus = t.laddus - 3; // copied slip -> the SAME box -> real laddus gone } public static void main(String[] args) { TiffinBox mine = new TiffinBox(); lunch(mine); System.out.println(mine.laddus); }}C:\Users\diya\Desktop\java-practice\class-09> javac LunchBreak.java
C:\Users\diya\Desktop\java-practice\class-09> java LunchBreak
1
NO — it prints 1. Recharge got a copy of a NUMBER: useless for changing main's balance. lunch got a copy of a SLIP: the copy still says "box #7", so line 6 opened your real box. Both methods received copies — Java never does anything else — but a copied box-number still opens the box.
Micro 8 — the last question anyone ever asks about this topic: the method holds a COPY of your slip. Fine — but what if the method crosses out the box number on its copy and writes a different one? Say it buys a brand-new tiffin box, #9, and scribbles "#9" over the "#7" on ITS slip. Does YOUR slip — in your pocket, untouched — suddenly say #9 too? Answer it in paper terms before any code: he scribbled on HIS copy, not on your slip. Watch the story first; then the program is just LunchBreak plus two lines.
MICRO-STORY 8 · NO CODE · THE NEW-BOX SWITCHEROO — ONE PIECE PER PRESS
So you still see box #7: 1 laddu. Not 4 (the eating in line 6 was real). Not 50 (that box is lost). ✓
Now the same story in Java — LunchBreak plus exactly two lines. You already know the answer.
MICRO 8 OF 8 · NewBoxTrick.java — LunchBreak + LINES 7 AND 8 · PREDICT: 4, 1 OR 50?
t = new TiffinBox() — and stuff the new box with 50 laddus. Does main print 4, 1 or 50?- Save as
NewBoxTrick.javainclass-09\ - Start from LunchBreak, add exactly TWO lines inside
lunch:t = new TiffinBox();thent.laddus = 50; - In
main: make one box, calllunch(mine);, printmine.laddus - Commit to 4, 1 or 50 BEFORE running
1 — line 6's eating was real; the re-point and the 50 lived only on the method's copy. This one run refutes "pass by reference".class TiffinBox { int laddus = 4; }public class NewBoxTrick{ static void lunch(TiffinBox t) { t.laddus = t.laddus - 3; // real — the copied slip opens YOUR box t = new TiffinBox(); // NEW LINE — re-points the COPY only t.laddus = 50; // NEW LINE — fills the box only the copy knows } public static void main(String[] args) { TiffinBox mine = new TiffinBox(); lunch(mine); System.out.println(mine.laddus); }}C:\Users\diya\Desktop\java-practice\class-09> javac NewBoxTrick.java
C:\Users\diya\Desktop\java-practice\class-09> java NewBoxTrick
1
1 — exactly the story. Line 6 was real (your box, 4−3). Line 7 crossed out only the COPY's slip — your slip never heard about box #9. Line 8's 50 laddus sit in a box nobody can find any more. A method can change your box's INSIDES; it can never swap which box YOUR slip points at. Check every line against the verdict table below.
The line-by-line verdict — match the code to the story: only THREE lines of NewBoxTrick.java did anything interesting, and you watched every one of them happen as boxes and slips BEFORE you read the code. Read each row and check it against your prediction:
| LINE | WHAT IT REALLY DOES | DOES main SEE IT? |
|---|---|---|
| LINE 6 | t.laddus = t.laddus - 3 — opens YOUR real box #7 through the copied slip and eats | YES — 4 becomes 1 |
| LINE 7 | t = new TiffinBox() — re-points only the COPY at a brand-new box #9 | NO — your own slip never moved |
| LINE 8 | t.laddus = 50 — fills the NEW box that only the copy knows about | NO — lost when the method ends |
Wrong — and the examiners know students say it. If Java were truly pass-by-reference, line 7's t = new TiffinBox() would have swapped YOUR slip too, and NewBoxTrick would print 50. It printed 1. That single run refutes the phrase. Say "references are passed by value" — the slip is copied, never the box — and bank both marks.
Breathe — the hardest topic of Unit 1 is behind you, and it never got a chance to be scary: eight micro-programs, none over 16 lines, each one small enough to hold in one hand. Close the laptop and answer these five from the stories alone — if all five come out right, you own Class 9's core:
| ASK YOURSELF | THE STORY THAT ANSWERS IT | ANSWER |
|---|---|---|
| A method gets my number — can it change my variable? | Recharge / Homework: it scribbles on its own page | Never |
Two variables, one new — how many objects? | TiffinShare / PaintTeam: many slips, ONE box | One — that's aliasing |
| I change the object through one name — what do the other names see? | PaintTeam: everyone sees blue, instantly | The change — there's only one object to see |
| A method gets my object — can it change the object's fields? | LunchBreak: a copied slip opens the same box | Yes |
| Can a method make my variable point somewhere else? | NewBoxTrick: it crossed out its own copy | Never |
And the whole part in one sentence for the exam: "Java always passes a copy — of the number for primitives, of the reference (the slip) for objects; so methods can change an object's contents but never the caller's variable." Everything left in today's class — static, the memory map, even the garbage collector — is gentler than what you just finished.
PART 4 · THE static KEYWORD
28,000 students. ONE college name.
Why store it 28,000 times?
Before any code — the mess hall. Each student's plate is their own: one per person, holds their own food. The menu board is different: ONE board, everyone reads the SAME board, and repainting it changes what every student sees. Java has a word for menu-board facts: static. That's the entire keyword. Everything below is just plates and boards.
| MESS HALL | JAVA WORD | HOW MANY EXIST? | EXAMPLE |
|---|---|---|---|
| Your plate | instance field (no keyword — the C8 default) | one PER object | String name; — Diya's name ≠ Rohit's name |
| The menu board | static field | exactly ONE, owned by the class | static String college; — same for all 28,000 |
| The head-count clicker at the door | static counter | ONE shared tally | static int totalAdmitted; — every admission ticks it |
static stores it once, on the class itself. Saving ratio ≈ 28,000 : 1.FIRST, THE SMALLEST POSSIBLE static — SEVEN LINES, ONE IDEA, ZERO OBJECTS
static: hang ONE menu board on the class itself and read it with ZERO objects — no constructor, no new, nobody in the hall.- Save as
MessBoard.javainclass-09\ - One field:
static String todaysSpecial = "Veg Biryani"; - In
main: print it through the CLASS name —MessBoard.todaysSpecial - Seven lines total; nothing else in the file
Veg Biryani — the board exists before any object does.public class MessBoard{ static String todaysSpecial = "Veg Biryani"; // the menu board — ONE copy public static void main(String[] args) { System.out.println(MessBoard.todaysSpecial); // CLASS name — no object, no new }}C:\Users\diya\Desktop\java-practice\class-09> javac MessBoard.java
C:\Users\diya\Desktop\java-practice\class-09> java MessBoard
Veg Biryani
Look at what is NOT in this file: no constructor, no new, no objects — nobody has entered the mess hall, yet the board already hangs on the wall and main read it through the CLASS name. That is the entire meaning of static, in seven lines. Everything below only adds plates around this board.
Before the file — one more mess-hall question, and it births the static METHOD: plates and boards settle where FACTS live. But now the principal asks: "how many students have been admitted so far?" Who do you ask? Not Diya — her plate doesn't know the total. Not Rohit. NO single plate owns that answer — the door CLICKER does, and the clicker belongs to the hall itself. So Java needs a method you can ask without picking any object — a method that lives on the CLASS, right next to the board and the clicker. Write static in front of a method and it becomes exactly that: callable as Student.getTotal() — class name, no object, no new.
main is static for PRECISELY this reason — when the JVM starts your program, zero objects exist yet, so the entry method cannot belong to any object. Every public static void main you have ever typed was this exact idea, waiting for today. Nothing new is being sprung on you — the name is finally catching up with your fingers.The plot summary before the file — so nothing ambushes you: the 23 lines below do only THREE things, and you have already met all three in the mess hall. Predict the three output lines before pressing:
| LINES | WHAT THEY DO — IN MESS-HALL WORDS | WHAT WILL PRINT |
|---|---|---|
| 3–5 | hang the menu board + the door clicker (ONE each, on the class) · declare the per-student plate | nothing yet |
| 6–10 | the birth certificate: write the plate's name, tick the SHARED clicker | nothing yet |
| 17–21 | two admissions, then three questions: the plates? the board? the clicker? | Diya | Rohit · the college line · Admitted: 2 |
STUDENT v5 · A COMPLETE, RUNNABLE FILE — ONE BOARD, ONE CLICKER, TWO PLATES — LINE PER PRESS
- Save as
Student.javainclass-09\ static String college+static int totalAdmitted(shared) ·String name(per object)- Constructor sets the name AND ticks
totalAdmitted static int getTotal()returns the tally — callable with NO objectmain: admit"Diya"and"Rohit", print the two names, thenStudent.college, then"Admitted: " + Student.getTotal()
Diya | Rohit · Vasavi College of Engineering · Admitted: 2 — two plates, one board, one clicker.public class Student{ static String college = "Vasavi College of Engineering"; // ONE copy static int totalAdmitted = 0; // ONE shared tally String name; // per-object Student(String name) { this.name = name; totalAdmitted = totalAdmitted + 1; // every birth ticks the SHARED tally } static int getTotal() // static method — no object needed { return totalAdmitted; } public static void main(String[] args) // complete file — runs on its own { Student s1 = new Student("Diya"); // plate 1 · clicker -> 1 Student s2 = new Student("Rohit"); // plate 2 · clicker -> 2 System.out.println(s1.name + " | " + s2.name); // two plates System.out.println(Student.college); // ONE board — read via the CLASS System.out.println("Admitted: " + Student.getTotal()); // ONE clicker }}C:\Users\diya\Desktop\java-practice\class-09> javac Student.java
C:\Users\diya\Desktop\java-practice\class-09> java Student
Diya | Rohit
Vasavi College of Engineering
Admitted: 2
Read the last two calls again: Student.college and Student.getTotal() — CLASS name, no object. That's the tell of static: it belongs to the blueprint, exists BEFORE the first new, and survives after the last. Two plates printed two names; one board and one clicker printed once each.
Math.sqrt(2), Math.max(a,b) — ever written new Math()? Never. Every Math method is static: pure computation, no per-object facts needed. And main itself is static — the JVM must enter BEFORE any object of your class exists. You have been WRITING a static method since your very first program.javac Student.java then java Student, the same two commands you've used since Class 2, and you'll see these exact three lines.Inside getTotal(), writing return name; is a COMPILE ERROR — "non-static variable name cannot be referenced from a static context". Why: getTotal() runs on the CLASS; name lives on an OBJECT. Which object's name would it mean? There might be zero, or 28,000. The compiler refuses to guess. (This is exactly why main can't use instance fields without creating an object first — the error message you've been squinting at since Class 3.)
THE TWO ZONES — WATCH WHY THE COMPILER REFUSES, PRESS BY PRESS
Every "static context" error in your life comes from one picture. Memory has a class zone (the method area — born the instant the class loads, before any object) and an object zone (the heap — empty until a new runs). Watch what exists WHEN, and the refusal explains itself:
FIVE PRESSES · CLASS ZONE FIRST — OBJECT ZONE ONLY AFTER new — THE RED ARROW IS THE ERROR MESSAGE
Static code has no this — no "current object" in its pocket. Hand it an address (s1) and every door opens.
| YOU ARE STANDING IN… | STATIC MEMBERS (class zone) | INSTANCE MEMBERS (object zone) |
|---|---|---|
| a static method — main, getTotal() | ✓ directly — same zone | only WITH an address: s1.name ✓ · bare name ✗ compile error |
| an instance method — printCard() | ✓ directly — the class zone always exists | ✓ directly — the method arrived WITH an object (its this) |
s1.printCard() — so by the time its body runs, it is holding an address (this = s1). It never has to ask "which object?"; the caller already answered. A static method is called through the CLASS — nobody handed it any object, so it has no this to offer. One direction is free, the other needs a ticket: instance→static always works; static→instance needs an object first.main is static — it starts in the class zone at a moment when the object zone is EMPTY. Every program you've written since Class 8 does Student s1 = new Student(...) first for this one reason: main must BUILD the object zone before it can touch anything in it. The line you've typed a hundred times was never ceremony — it was the ticket.BUT WAIT — s1.college ALSO COMPILES. IS THE BOARD ON THE PLATE AFTER ALL?
Type System.out.println(s1.college); and it prints the college. So does s2.college. So does Student.college. Three spellings, three prints — did each plate secretly get its own board? Watch the arrows — they answer it better than any sentence:
THREE SPELLINGS ON THE CHIPS · ONE FIELD AT THE ARROWHEADS
Repaint through ANY spelling and ALL THREE read the new paint — there was only ever one board.
| VARIABLE | DECLARATION | HOW MANY COPIES? | CLEAREST ACCESS |
|---|---|---|---|
| college | static String college | 1 shared copy | Student.college |
| totalAdmitted | static int totalAdmitted | 1 shared copy | Student.totalAdmitted |
| name | String name | 1 per object | s1.name, s2.name |
The compiler silently reads s1.college as Student.college — it never even looks at which object s1 holds. Proof of how little the object matters: set s1 = null; and s1.college STILL prints the board, no crash — because the object was never consulted. So write the access the way the truth works, class name first: Student.college. One sentence for the exam: static data belongs to the class; instance data belongs to the individual object.
name lives there). Writing s1.college just makes Java glance UP at s1's class and read the shelf. Many slips to one box = aliasing; many spellings to one class field = static. Different mechanisms, same happy ending: one truth.One sentence to keep — and breathe: ask of any fact — “is this the same for every object, or different per object?” Same-for-all means menu board, means static. Different-per-object means plate, means instance. That one question is the WHOLE keyword — the seven-line MessBoard, the 23-line Student, and every exam question are just that question wearing different clothes. Today's Activity 1 is literally counting plates against one board — you are already ready for it.
PART 5 · SELF-STUDY CORNER
First, what is a block?
Then — two rare ones to recognise.
A block is simply a pair of braces { … } holding zero or more statements, treated by Java as ONE unit. Count the blocks you already own: the class body is a block, every method body is a block, every if / for / while body is a block. Your Allman-style opening brace on its own line has been drawing block boundaries for you all semester.
And a block does one powerful thing besides grouping: it owns a scope. A variable declared inside a block is born at its declaration and dies at the closing } — exactly the "one box, one label, one block" rule from Class 3, and exactly why a loop counter vanishes after the loop.
if. Java also allows a bare block to sit directly inside the class body, attached to nothing. Such a block is called an initializer block, and Java runs it at a fixed moment: a plain one (an instance initializer block) runs before EVERY constructor; write static in front of it (a static block) and it runs exactly ONCE, when the class loader shelves the class. Watch both in one file below — line 3 is the static block, line 4 is the instance block.new BlockOrder() TWICE. Which lines print, in what order, how many times each?- Save as
BlockOrder.javainclass-09\ - Line 3:
static { … }printing"1. static block — class loads" - Line 4: a bare
{ … }block printing"2. instance block — before EVERY constructor" - Constructor prints
"3. constructor";mainruns twonews - Write your predicted order in the notebook FIRST
1, 2, 3, 2, 3 — the static block once at class load; the instance block before EVERY constructor.public class BlockOrder{ static { System.out.println("1. static block — class loads"); } { System.out.println("2. instance block — before EVERY constructor"); } BlockOrder() { System.out.println("3. constructor"); } public static void main(String[] a) { new BlockOrder(); new BlockOrder(); }}C:\Users\diya\Desktop\java-practice\class-09> javac BlockOrder.java
C:\Users\diya\Desktop\java-practice\class-09> java BlockOrder
1. static block — class loads
2. instance block — before EVERY constructor
3. constructor
2. instance block — before EVERY constructor
3. constructor
Static block: ONCE, when the class loader shelves the class (C6 room 1!). Instance block: before EVERY constructor run — so it prints twice for two news. That asymmetry IS the exam question.
this(...) chaining, most teams prefer the chain.ONE MORE — THE SAME TWO BLOCKS DOING A REAL JOB (instructor add-on 2026-08-21)
BlockOrder proved the ORDER — GameLobby shows the WHY. Open any game: the season's map pool downloads ONCE, the moment the game code loads — not per player, that would be madness. But EVERY player who joins gets the daily +50 login coins before their own welcome message, no matter which door (constructor) they came in through. That is exactly the two blocks: static block = expensive one-time class setup · instance block = the shared line every constructor must not forget.
- Save as
GameLobby.javainclass-09\ - Static block prints
"[once] season map pool loaded" - Bare instance block prints
"+50 daily login coins" - Constructor stores the player's name and prints
"<name> joined the lobby" mainadmits"Diya"and"Rohit"— predict the five lines FIRST
[once] exactly once and FIRST, then the +50/joined pair per player.public class GameLobby{ static { System.out.println("[once] season map pool loaded"); } { System.out.println("+50 daily login coins"); } String player; GameLobby(String joiningPlayer) { player = joiningPlayer; System.out.println(player + " joined the lobby"); } public static void main(String[] a) { new GameLobby("Diya"); new GameLobby("Rohit"); }}C:\Users\diya\Desktop\java-practice\class-09> javac GameLobby.java
C:\Users\diya\Desktop\java-practice\class-09> java GameLobby
[once] season map pool loaded
+50 daily login coins
Diya joined the lobby
+50 daily login coins
Rohit joined the lobby
Count again: [once] printed ONCE for two players — class-level setup, exactly like the map pool. The +50 line printed per player, BEFORE each welcome — the instance block keeping its promise to every constructor. Same order law as BlockOrder, now with a reason to exist.
PART 6 · THE MEMORY MAP
Three regions. Every variable you've
ever written lives in exactly one.
Gently now — because you have ALREADY met all three regions today without their official names. Part 3's notebook pages and pocket slips? They live on the stack. The common fridge where every tiffin box actually sat? That is the heap. Part 4's menu-board wall where static things hang? That is the method area. Nothing in this part is new — we are only writing the real names on the places you have been walking through all class. Watch the map assemble one cell per press — every cell is a real thing from YOUR Lab-1 BookDriver run.
BUILD-UP · YOUR LAB-1 RUN, X-RAYED — ONE CELL PER PRESS
One run · three regions: frames on the stack, objects on the heap, the class + its statics on the shelf. ✓
Now re-read Part 3 with this map: lunch() copied a STACK cell (the slip) — the HEAP object (the box) never moved. It all clicks.
| QUESTION | STACK | HEAP |
|---|---|---|
| Holds what? | method frames: primitives + references (address slips) | every object and array that new makes |
| Lifetime? | born at call, dies at return — automatic, instant | born at new, dies when the GC proves it unreachable |
| Speed & size? | tiny, blazing fast (push/pop) | large, managed — the GC's territory (next part) |
| One per…? | THREAD (each worker gets its own — C6 room 4) | JVM — ONE heap shared by every thread |
The line that survives every exam: "primitives live where they're declared; objects live on the heap; variables of object type hold only the address." Ten words of it — "the variable is the slip, the object is the house" — will carry you through Units 1 to 5.
PART 7 · ACTIVITY 1 · PREDICTION
Four books issued.
What does the shared tally say — at each step?
A Library class keeps static int totalBooksIssued, incremented in the constructor. Four Book issues happen one after another. Notebook first — write the counter's value after EACH line.
GIVEN The complete program below — read it line by line. class Library keeps static int totalBooksIssued = 0;, the constructor runs totalBooksIssued++;, and main prints the tally after each of the four marked lines.
TASK In your notebook: the value of Library.totalBooksIssued after each of L1–L4, plus ONE sentence answering: "why did L3 not change it?" Then predict what line 19's a.totalBooksIssued prints (yes, via a, not the class).
public class Library{ static int totalBooksIssued = 0; // ONE shared tally — Part 4's clicker Library() { totalBooksIssued++; // every REAL issue ticks it } public static void main(String[] args) { Library a = new Library(); // L1 System.out.println(Library.totalBooksIssued); Library b = new Library(); // L2 System.out.println(Library.totalBooksIssued); Library c = b; // L3 — look closely: no new! System.out.println(Library.totalBooksIssued); Library d = new Library(); // L4 System.out.println(Library.totalBooksIssued); System.out.println(a.totalBooksIssued); // legal? what prints? }}Four numbers + one sentence. Ninety seconds. No peeking.
| STEP | WHAT RUNS | CONSTRUCTOR FIRES? | totalBooksIssued |
|---|---|---|---|
| L1 | new Library() | YES — tally +1 | 1 |
| L2 | new Library() | YES — tally +1 | 2 |
| L3 | c = b (no new!) | NO — copies an address slip only | 2 · the trap |
| L4 | new Library() | YES — tally +1 | 3 |
- THE SENTENCEL3 creates no object —
c = bonly copies b's slip — Part 3's TiffinShare move! Two names, one object, no constructor run, so the shared tally never hears about it. Count news, not variable names. - a.totalBooksIssuedPrints 3 — legal but misleading: Java quietly reads the CLASS's one shared copy through the object. Style rule: always write
Library.totalBooksIssuedso readers see it's static. - MEMORY MAPa, b, c, d = four STACK slips · three Library objects on the HEAP (b and c share one) · totalBooksIssued = ONE cell on the METHOD-AREA shelf. All three regions in one activity.
PART 8 · ACTIVITY 2 · CLASSIFICATION
Six members of a HostelRoom.
Which belong to the class, which to each room?
The exam's favourite 2-mark shape: here are members, sort them. The test question is always the same — "is this fact the same for every object, or different per object?" Notebook: write S (static), I (instance) or C (constant) against each.
CLASSIFY The six members, in their real home — the class skeleton below. Write S (static), I (instance) or C (constant) against ①–⑥ in your notebook.
public class HostelRoom{ int roomNumber; // ① static int totalRoomsBooked; // ② String occupantName; // ③ static final String HOSTEL_NAME = "Vasavi Nilayam"; // ④ double monthlyRent; // ⑤ static double messFeePerMonth; // ⑥}One test question, six times: same for every room, or not?
The whole skill in one line: same-for-all means static · same-for-all AND unchangeable means static final · varies-per-object means instance.
PART 9 · GARBAGE COLLECTION
You have never freed memory.
Someone has been doing it for you.
Story first, one small question: at the end of a mess-hall meal, who clears your plate? Not you — the cleaning staff do, and they follow ONE simple rule: if nobody is sitting at the plate any more, it goes. Java's heap has the same staff. In three classes and two labs you have created dozens of objects and never once cleaned one up — zero deallocation lines — because the JVM's janitor (Class 7 waved at him) has been quietly clearing every abandoned plate. Today, his one and only rule, in his own words: reachability — "is anyone still at this table?"
WATCH IT HAPPEN · THE LIFE AND DEATH OF 52 — ONE FRAME PER PRESS
shelf[0] = new Book("Wings of Fire", ...); — 52 born, slip writtenshelf[0] = new Book("Ponniyin Selvan", ...); — same slot, slip REWRITTEN → 52 loses its last slipYour job: drop the slips. The janitor's job: everything else.
NOW TYPE THE PICTURE — THE SAME LIFE-AND-DEATH IN NINE LINES OF main · LINE PER PRESS
- Save as
PlateSweep.javainclass-09\ - Tiny helper class:
class Plate { String owner; }+ a one-line constructor - In
main:Plate p = new Plate("Diya — lunch");, print it, thenp = new Plate("Diya — dinner");— NO second variable - End with
System.gc();and one honest print about what it does (and doesn't) promise
class Plate{ String owner; Plate(String owner) { this.owner = owner; }}public class PlateSweep{ public static void main(String[] args) { Plate p = new Plate("Diya — lunch"); // plate 1 born · slip written System.out.println(p.owner + " plate in use"); p = new Plate("Diya — dinner"); // slip REWRITTEN — plate 1 unreachable System.out.println(p.owner + " plate in use"); System.gc(); // a polite REQUEST — never an order System.out.println("lunch plate: eligible — the JVM decides when"); }}C:\Users\diya\Desktop\java-practice\class-09> javac PlateSweep.java
C:\Users\diya\Desktop\java-practice\class-09> java PlateSweep
Diya — lunch plate in use
Diya — dinner plate in use
lunch plate: eligible — the JVM decides when
Line 12 is the SVG's "SLIP REWRITTEN" moment in real code — after it, NOTHING can ever reach the lunch plate again. And read line 14 honestly: System.gc() only requests a sweep; the JVM may run it now, later, or not at all. That one sentence — "eligible, not deleted; you decide whether, the JVM decides when" — is the 2-mark GC answer in full.
False twice over. First: it only removes ONE slip — if any other reference (a b/c pair from Activity 1!) still points there, the object stays fully alive. Second: even a truly unreachable object is not deleted at that instant — only marked eligible. Exact phrase for full marks: "assigning null makes an object eligible for garbage collection only if no other reference to it remains."
Connect it to the arithmetic you already own: Class 7's JIT tally proved the JVM watches your code run. GC is the same instinct pointed at memory: watch, prove, THEN act. Nothing in the JVM is manual bookkeeping — it's all measurement. That is the deepest habit Java has: measure, don't trust.
PART 10 · SELF-STUDY CORNER
Why the GC sorts objects by age.
Measured across real programs: roughly 90%+ of objects become unreachable almost immediately — loop temporaries, intermediate Strings, short-lived frames' leftovers. Your Lab-1 Books lived to the last println; most objects don't.
So the heap is split: newborns go to the young generation, swept often and fast; survivors of several sweeps get promoted to the old generation, swept rarely. Effort goes where the garbage is.
If 90% of garbage is young, sweeping ONLY the young region finds 90% of the trash for a fraction of the work — like clearing the mess hall's tables hourly but deep-cleaning the store-room monthly. Same measure-first instinct as the JIT.
PART 11 · THE final CONSTANT
Some values must never move.
Make the compiler your bodyguard.
Story first: the campus movie hall was BUILT with 120 seats — bricks and cement decided that number, not code. If any line of Java could quietly change it to 200, the app would happily sell 80 tickets to seats that do not exist. Java's protection is one word: final on a variable means assigned once — any re-assignment is a COMPILE ERROR. Not a runtime check, not a convention — the build physically refuses. Convention completes it: constants are named in ALL_CAPS and usually declared static final (shared AND permanent — Activity 2's ④).
FIRST, THE SMALLEST POSSIBLE final — EIGHT LINES, ONE REFUSAL
final: assign a value once, then TRY to re-assign it — and watch the build physically refuse to produce a program.- Save as
TinyFinal.javainclass-09\ - In
main:final int seats = 120;— assigned once, legal forever - Next line, on purpose:
seats = 200; - Run
javacand read the refusal slowly
cannot assign a value to final variable seats — and no .class file is produced at all.public class TinyFinal{ public static void main(String[] args) { final int seats = 120; // decided once… seats = 200; // …so THIS line cannot exist }}C:\Users\diya\Desktop\java-practice\class-09> javac TinyFinal.java
TinyFinal.java:6: error: cannot assign a value to final variable seats
seats = 200;
^
1 error
Two hot lines, one lesson: line 5 assigns ONCE (legal, forever), line 6 tries a second assignment and the BUILD refuses — no .class file is produced at all. You cannot even create a program that breaks a final. That is the entire keyword; the bigger file below just gives the frozen number a job worth doing.
The plot before the code — two acts, both simple: ACT 1, the honest run: the file has ONE guard ("if this booking would cross 120, refuse and answer false; otherwise accept and answer true") and a main that tries to book 100 seats, then 30 more. Predict the two printed words — you can do it from this sentence alone. ACT 2, the sabotage: we then try to sneak MAX_SEATS_PER_SHOW = 200; into the file on purpose — and enjoy watching the compiler refuse to build it.
- Save as
MovieShow.javainclass-09\ - Constant:
static final int MAX_SEATS_PER_SHOW = 120;+ fieldsmovieName,seatsBooked boolean bookSeats(int n): ifseatsBooked + ncrosses 120 returnfalse; else book and returntruemain: book 100 seats, then 30 more, printing each result- ACT 2: add
MAX_SEATS_PER_SHOW = 200;insidebookSeatsand re-compile
true then false. Sabotage run: cannot assign a value to final variable MAX_SEATS_PER_SHOW — the overselling program cannot even be built.public class MovieShow{ static final int MAX_SEATS_PER_SHOW = 120; // the hall's physical size String movieName; int seatsBooked = 0; boolean bookSeats(int n) { if (seatsBooked + n > MAX_SEATS_PER_SHOW) { return false; // house full — physics wins } seatsBooked = seatsBooked + n; return true; } public static void main(String[] args) // complete file — watch the guard work { MovieShow evening = new MovieShow(); System.out.println(evening.bookSeats(100)); // fits: 100 <= 120 System.out.println(evening.bookSeats(30)); // 130 > 120 — the guard refuses }}C:\Users\diya\Desktop\java-practice\class-09> javac MovieShow.java
C:\Users\diya\Desktop\java-practice\class-09> java MovieShow
true
false
// now the sabotage: add inside bookSeats():
// MAX_SEATS_PER_SHOW = 200;
C:\Users\diya\Desktop\java-practice\class-09> javac MovieShow.java
MovieShow.java:9: error: cannot assign a value to final variable MAX_SEATS_PER_SHOW
MAX_SEATS_PER_SHOW = 200;
^
1 error
First the honest run: 100 seats fit (true), 30 more would over-fill (false) — the guard works. Then the sabotage: not a warning — a refusal, no .class file at all. The overselling bug that would have crashed the show at 8 pm is IMPOSSIBLE to compile at 4 pm. That's the trade final offers: flexibility for certainty.
ACTIVITY 3 The campus movie club is computerising. In your notebook, design ONE final constant for the MovieShow class — full declaration (modifiers, type, ALL_CAPS name, value) — for the club's rule: "a member may book at most 4 tickets per show." Then ONE sentence: why must this value not be reassignable at runtime?
One line of Java + one sentence of why.
- DECLARATION
static final int MAX_TICKETS_PER_MEMBER = 4;— static (one rule for the whole club, not per show), final (assigned once), ALL_CAPS (readers see "constant" instantly). - THE WHYIf any code path could re-assign it — a typo, a "quick fix" at the counter — the fairness rule silently dies and one member books 40 seats. final turns a policy into a compile-time guarantee: the program that oversells cannot even be built.
- FWD · C10Today final froze a value. Class 10 shows final freezing a method (cannot be overridden) and a whole class (cannot be extended) — and the PYQ that wants all three in one answer.
PART 12 · BEFORE YOU GO
One question, five answers —
pack them tight.
| TODAY'S TOOLKIT | THE ONE LINE THAT EARNS THE MARKS |
|---|---|
| The copy rule (pass-by-value) | Java always copies. Primitives: the number itself. Objects: the slip, never the box — "references are passed by value", never "by reference". Many slips to one box = aliasing. |
| static | One copy on the class shelf; exists before any object; Class.member to access; static methods can't touch instance fields. |
| Stack vs heap | Frames + primitives + slips on the stack (per thread) · every new on the heap (one, shared) · class + statics on the method-area shelf. |
| GC | Unreachable, then eligible, then swept when the JVM chooses. null removes one slip, deletes nothing. |
| final constant | Assigned once; re-assignment is a compile error; convention static final ALL_CAPS. Methods & classes: Class 10. |
java-practice\ holds lab-00\ class-02\ class-03\ class-04\ class-08\ lab-01\ and now class-09\. Same root since day one — one mkdir class-09 and you're home.Class 9 in one breath: "Java copies every argument — the number or the slip, never the box — shares one static copy per class, stacks the frames, heaps the objects, sweeps the unreachable, and lets final make a value permanent." Say it twice before you leave; it answers five different exam questions.