Java Unit 2 · Crash Course
All modules
010203040506070809101112131415 Glossary
Java logo OOP Through Java · Unit 2

Classes & Interfaces,
Exception Handling,
Multithreaded Programming.

Fifteen modules, one Eclipse project, and every verbatim previous-year question answered in full — built for a student picking this up with nothing but the syllabus.

what this unit covers
SingletonAbstractNested classesInterfacesPackagesExceptionsThreadsDeadlock
9.0 hrs across 4 sittings
How do you want to read this?
You can switch inside any module at any time. Whatever you pick here becomes the starting point.
Java Package Explorer
Unit2Project project
src source folder
school package
ClassMonitor.java new
Reservation.java new
safety package
Library.java new
Your project, folder by folder
15
modules
18
verbatim PYQs
9.0 hrs
over 4 sittings
~89
chunks

The syllabus, line by line

Official R-24 wording for Unit 2, with the module that covers each phrase.

UI24PC320CS · OOP Through Java · Unit 2 19 syllabus items · 19 covered so far
Classes and Interfaces
Singleton classModule 2
Abstract classModule 3
Nested classModule 4
InterfaceModule 5
PackageModules 6–7
Exception Handling
IntroductionModule 8
Types of exceptionsModule 9
Syntax of exception handling codeModule 8
Multiple catch statementsModules 8, 10
Using finally statementModule 8
User-defined exceptionsModules 9–10
Multithreaded Programming
Introduction to threads, creating threadsModule 11
Extending the Thread classModule 11
Implementing the Runnable interfaceModule 11
Life cycle of a threadModule 11
Priority of a threadModule 12
SynchronizationModule 12
Inter-thread CommunicationModule 13
DeadlockModule 13

The module tree

Grouped the way the Eclipse Package Explorer would show it — click a folder to expand.

singleton / access packages exceptions threads
Kickoff Module 1 · 10 min
01
Orientation & bridge from Unit 1
open0:00 – 0:10
2 chunks · 0:00 – 0:10
1Welcome to Unit 20:00 – 0:06
2What Unit 1 left you with0:06 – 0:10
Classes & Interfaces Modules 2–5 · 3.0 hrs · 3 PYQs
02
Singleton Classes — the class monitor
openessential1 PYQ0:00 – 0:45
6 chunks · 0:00 – 0:45
1Why this pattern exists0:00 – 0:05
2What new actually does0:05 – 0:12
3Setting up the file in Eclipse0:12 – 0:22
4Worked example — proving it works0:22 – 0:32
5When the one instance gets built0:32 – 0:40
6Exam landing0:40 – 0:45
03
Abstract Classes — the Reservation hierarchy
open1 PYQ0:00 – 0:45
7 chunks · 0:00 – 0:45
1When an unfinished class is the right answer0:00 – 0:06
2What happens if you try to build the blueprint itself0:06 – 0:12
3Worked example — one abstract, one concrete, two subclasses0:12 – 0:22
4Can an abstract class have a constructor?0:22 – 0:29
5Why reach for one — and when not to0:29 – 0:34
6Exam landing0:34 – 0:41
7Checkpoint — add a third subclass0:41 – 0:45
04
Nested & Inner Classes — static, inner, anonymous
openessential0:00 – 0:45
6 chunks · 0:00 – 0:45
1A class that only makes sense inside another0:00 – 0:07
2Static nested class0:07 – 0:16
3Inner class — the non-static one0:16 – 0:26
4Anonymous inner class0:26 – 0:34
5All three, side by side0:34 – 0:40
6Checkpoint — pick the right form0:40 – 0:45
05
Interfaces — the Library contract
open1 PYQ0:00 – 0:45
7 chunks · 0:00 – 0:45
1An agreement anyone can sign0:00 – 0:07
2The smallest working example0:07 – 0:15
3Signing more than one agreement0:15 – 0:24
4Two newer additions: default and static0:24 – 0:31
5Exam landing0:31 – 0:38
6Interface vs abstract class0:38 – 0:42
7Checkpoint — which one, and why0:42 – 0:45
Packages Modules 6–7 · 80 min · 5 PYQs
06
Concept & Manual Creation — Notepad++, javac -d
open0:00 – 0:35
7 chunks · 0:00 – 0:35
1A package is a folder0:00 – 0:05
2Building it by hand0:05 – 0:11
3Compiling it yourself0:11 – 0:18
4The finished structure0:18 – 0:22
5Two packages, joined by import0:22 – 0:29
6The two mistakes everyone makes0:29 – 0:33
7Recap — and what Module 7 will remove0:33 – 0:35
07
Eclipse Method & Access Control — New → Package wizard
open5 PYQs0:00 – 0:45
10 chunks · 0:00 – 0:45
1The same thing, in two clicks0:00 – 0:05
2Who is allowed to see what0:05 – 0:10
3Worked example — across two packages0:10 – 0:16
4Second example — change one thing, change the outcome0:16 – 0:20
5Encapsulation — what the four levels are for0:20 – 0:25
6final — the other way to restrict0:25 – 0:30
7Immutable classes0:30 – 0:34
8The four pillars, all in hand0:34 – 0:37
9Exam landing0:37 – 0:42
10Checkpoint — choose the modifier0:42 – 0:45
Exception Handling Modules 8–10 · 2.0 hrs · 6 PYQs
08
Fundamentals — try / catch / finally
open0:00 – 0:40
7 chunks · 0:00 – 0:40
1When a program stops rather than continues0:00 – 0:07
2try and catch — fixing that exact crash0:07 – 0:14
3Multiple catch blocks0:14 – 0:21
4finally — the block that always runs0:21 – 0:27
5The three you will meet most0:27 – 0:32
6Worked example — everything together0:32 – 0:37
7Checkpoint — predict the output0:37 – 0:40
09
Types, throw vs throws, Custom
open1 PYQ0:00 – 0:40
7 chunks · 0:00 – 0:40
1Two families of exception0:00 – 0:07
2Exam landing0:07 – 0:13
3throw and throws0:13 – 0:19
4Writing your own exception0:19 – 0:26
5Why bother writing your own0:26 – 0:31
6Worked example — custom exception plus multiple catch0:31 – 0:36
7Checkpoint0:36 – 0:40
10
Integration & Full PYQ Landings — bank account, insurance, invalid age
open5 PYQs0:00 – 0:40
8 chunks · 0:00 – 0:40
1Everything, in one program0:00 – 0:06
2Exam landing — multiple catch0:06 – 0:11
3Exam landing — insurance hierarchy0:11 – 0:18
4Exam landing — the BankAccount array0:18 – 0:25
5Exam landing — the re-entry loop0:25 – 0:30
6Exam landing — three named types in one program0:30 – 0:35
7The two habits to avoid0:35 – 0:38
8Teach-back — closing Exception Handling0:38 – 0:40
Multithreading Modules 11–13 · 2.0 hrs · 4 PYQs
11
Fundamentals — Thread vs Runnable, lifecycle
open3 PYQs0:00 – 0:40
6 chunks · 0:00 – 0:40
1More than one thing at a time0:00 – 0:07
2Making one, by extending Thread0:07 – 0:15
3The second way — implementing Runnable0:15 – 0:22
4Worked example — two cooks at once0:22 – 0:28
5The life of a thread0:28 – 0:35
6Checkpoint0:35 – 0:40
12
Priority & Synchronization — BookMyShow seat-booking race
open1 PYQ0:00 – 0:40
6 chunks · 0:00 – 0:40
1Priority, and asking a thread to wait0:00 – 0:07
2Two people, one seat0:07 – 0:16
3The fix — one word0:16 – 0:24
4Settling a question from Module 20:24 – 0:30
5Exam landing0:30 – 0:35
6Checkpoint — find the bug0:35 – 0:40
13
Inter-thread Communication & Deadlock
open0:00 – 0:40
6 chunks · 0:00 – 0:40
1Threads that wait for each other0:00 – 0:08
2Worked example — one cook, one server0:08 – 0:18
3Deadlock — both waiting, neither moving0:18 – 0:26
4The fix — everyone picks up in the same order0:26 – 0:32
5The four mistakes, across the whole topic0:32 – 0:36
6Teach-back — closing Multithreaded Programming0:36 – 0:40
Wrap-up Modules 14–15 · 30 min
14
Unit Recap — cheat sheet & folder tree
open0:00 – 0:15
2 chunks · 0:00 – 0:15
1The whole unit, one card per topic0:00 – 0:10
2Everything you built, and how to keep it0:10 – 0:15
15
Timed Self-Assessment — all 18 PYQs, worked solutions
open0:00 – 0:15
2 chunks · 0:00 – 0:15
1Eight minutes, seven topics0:00 – 0:08
2Solutions0:08 – 0:15
Module 1 · Kickoff & Orientation
0%
10 min
next   back   chunk
CHUNK 1 OF 20:00 – 0:06
MODULE 1 · KICKOFF & ORIENTATION
Unit 2 · OOP Through Java · UI24PC320CS

Classes & Interfaces · Exception Handling · Multithreaded Programming

Fifteen modules that build one Eclipse project from an empty folder to a working multithreaded program. Every line is typed, run, and shown with its real console output — and every previous-year question is answered in full where it belongs.

SingletonAbstractNestedInterfacesPackagesExceptionsThreads
19
syllabus items
18
exam questions
44
java files
9.0
hours
UNIT 2 · SIX TOPICS, FIFTEEN MODULES Classes & Interfaces Modules 2 to 7 Exception Handling Modules 8 to 10 Multithreading Modules 11 to 13 every topic gets its own runnable programs and its own past questions Modules 14 and 15 revise
Three syllabus areas · fifteen modules · one project folder
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

A short orientation before Unit 2's Java content begins.

One point per press
Nothing is dumped on you at once — the next idea appears only when you're ready for it.
Code builds line by line
You watch a program assemble the way you'd actually type it, with its output growing alongside.
Two voices, same content
Teaching Mode reads like a live class; Learning Mode reads for quiet study. Code and answers are identical.

The exact syllabus — and where each line lands

The official Unit 2 syllabus (UI24PC320CS, R-24), with the module that covers each phrase.

Classes and Interfaces
Singleton classModule 2
Abstract classModule 3
Nested classModule 4
InterfaceModule 5
PackageModules 6–7
Exception Handling
Introduction, types of exceptionsModules 8–9
Syntax of exception handling codeModule 8
Multiple catch statementsModules 8, 10
Using finally statementModule 8
User-defined exceptionsModules 9–10
Multithreaded Programming
Introduction to threads, creating threadsModule 11
Extending the Thread classModule 11
Implementing the Runnable interfaceModule 11
Life cycle of a threadModule 11
Priority of a threadModule 12
SynchronizationModule 12
Inter-thread CommunicationModule 13
DeadlockModule 13

The workspace you'll live in

JDK 21 and Eclipse assumed installed. Three panels recur throughout the unit: Package Explorer (left), editor (centre), Console (bottom).

Unit2Project
src
— empty for now —
no file open
// your first file appears here
// in Module 2
Console
> nothing run yet

Nothing new here. Every Unit 2 example is this same shape with more added — the private field, the constructor that fills it, the method that reads it. If any line above is unfamiliar, revisit Unit 1 before Module 2.

Package Explorer is where your folder tree lives — every module ends by showing you what it looks like. The Console is where every output in this unit appears.

The one move you'll repeat all unit

Almost everything you make in Eclipse starts the same way — File → New → then whatever you want:

A project — done once, right now.
A package — a folder to group related classes.
A class — the file you will create dozens of times.

Watch the cursor below. It opens File, rests on New until the second menu slides out, then lands on Java Project. Three stops, always in that order.

1Click File in the menu bar, top-left of the Eclipse window
2Hover New — don't click, just rest on it until the side menu appears
3Click Java Project in that side menu

If the side menu closes before you reach it, you moved diagonally and slipped off New on the way. Travel right first, then down.

Creating the project — once, now

The wizard that opens has a lot on it. You only need the first box; everything else is already correct.

Type the project name exactly as shown — Unit2Project, one word, capital U and P, no spaces. Every folder path in this unit assumes that name, so a different spelling means translating every later instruction in your head.

1Type Unit2Project into Project name
2Leave JRE alone — "Use default JRE" is what you want
3Leave Project layout as it is — this is what gives you the src folder
4Press Finish. Not Next — nothing on the later pages concerns you
New Java Project
Project name:
Unit2Project
JRE:
Use default JRE — JavaSE-21
Project layout:
Create separate folders for sources and class files
Cancel
Finish

What you should see afterwards

Eclipse closes the wizard and Unit2Project appears in the Package Explorer on the left, with an empty src folder inside. That src folder is where every file in this unit will live.

Unit2Project
srcempty for now
JRE System Library [JavaSE-21]
Build the save habit now. Eclipse compiles a file the moment you save it, and only then. Press Ctrl+S after every change. If the Console shows old output, an unsaved file is the reason nine times out of ten.

That third setting is the one that creates the src folder every file in this unit lives inside. Leave it ticked.

CHUNK 2 OF 20:06 – 0:10

What Unit 1 left you with

Unit 2 builds on three things from Unit 1. The program below contains all three, labelled as they appear. If it reads comfortably, you're ready.

1A class — a blueprint describing what every Student object will hold and do
2A private field — data hidden inside the object, unreachable from outside code
3A constructor and a method — the way an object is built, and the way its hidden data is read
a Unit 1 refresher — read only, nothing to type
1public class Student
2{
3 private String name;
4
5 Student(String studentName)
6 {
7 name = studentName;
8 }
9
10 public String getName()
11 {
12 return name;
13 }
14}
Code on this page can't be copied — type it out. Typing is where it sticks.
Saving is what compiles it. Press Ctrl + S after typing. Eclipse builds the file on every save, so red marks appear immediately — before you ever press Run. Run with the green button or Ctrl + F11.
Class
The blueprint — line 1. It describes what every Student will have, without being one itself.
Object
A real thing made from that blueprint, created with new Student("Asha").
Constructor
Lines 5–8. Runs once, at creation, to set the object up. Note it shares the class's name.

Module 2 changes exactly one thing about that constructor — and that single change is the whole Singleton idea.

What's ahead

  • Singleton Classes
    a class that allows exactly one object of itself to ever exist.
    45 min
  • Abstract Classes
    a class that deliberately leaves part of itself unfinished for subclasses to complete.
    45 min
  • Nested Classes
    a class inside another, for pieces that only make sense as part of a larger whole.
    45 min
  • Interfaces
    a pure contract that unrelated classes can each agree to follow.
    45 min
  • Packages
    how a real project organises files into folders — built by hand first, then with Eclipse.
    80 min
  • Exception Handling
    catching what goes wrong at runtime instead of letting the program crash.
    2 hrs
  • Multithreading
    running more than one part of a program at the same time, safely.
    2 hrs

How to pace it

About nine hours total, split into four sittings. Every sitting ends on a completed topic — never mid-concept.

SITTING 1
1–4
~2.4 hrs
SITTING 2
5–7
~2.1 hrs
SITTING 3
8–10
~2.0 hrs
SITTING 4
11–15
~2.5 hrs

Eighteen previous-year questions land across these modules — each one answered in full, at the point its concept is taught, never saved for the end.

Checkpoint

Using the Student class above, answer these three, then open the worked answers to check.

1. Which line is the constructor, and how did you know?
2. Why can't you print a Student's name from outside the class right now?
3. What would change if the constructor were marked private?

Show worked answers
1. Lines 5–8. Two giveaways: it carries the class's own name (Student), and it has no return type — not even void. Those two together only ever describe a constructor.

2. The name field is private, so only code inside Student can touch it. Outside code would need a method the class chooses to offer.

3. Nothing outside the class could write new Student(...) anymore — creation would be blocked entirely unless the class provided its own way out. That's exactly the door Module 2 walks through.

Project so far

The project as it stands after Module 1 — empty. Module 2 adds the first file, and this tree grows cumulatively from there.

Unit2Project
  • src
    — nothing here yet —

Module 2 adds school/ClassMonitor.java — the first file in this project.

What Unit 2 adds to what you already write

You can already
Unit 2 adds
Because
write a class with fields and methods
control who may see and change them
a field anybody can edit is a field nobody can trust
make an object with new
decide how many may ever exist
some things must be shared, not copied
call a method and get an answer
say what happens when there is no answer
a program that cannot fail has not been finished
run statements one after another
run several at the same time
waiting for one slow thing should not stop everything
In our code
every row becomes a runnable program
in the module that teaches it

A quick refresher, worked through

Nothing to solve yet — these are the three Unit 1 ideas everything ahead sits on, each shown complete. Read them, then check yourself at the bottom if you like.
1 A class with a private field. Every example in this unit is built this shape: the data is hidden, and a method hands it out.
1class Book 2{ 3 private String title; 4 5 Book(String t) 6 { 7 title = t; 8 } 9 10 public String getTitle() 11 { 12 return title; 13 } 14}

The parameter is t and the field is title, so the two names never clash.

2 == compares objects, not contents. This matters more than it looks — Module 2 exists because of it.
1Book a = new Book("Wings of Fire"); 2Book b = new Book("Wings of Fire"); 3 4System.out.println(a == b);
false

Two objects were built, so matching titles change nothing. == asks "are these the same object in memory?" Module 2 is entirely about controlling this.

3 private blocks outside access. Writing a.title from another class does not compile.
The field Book.title is not visible

Outside code must go through getTitle(). Module 2 applies this same rule to a constructor instead of a field — that one move is what makes a Singleton work.

Optional — check yourself on these three
Cover the snippets above and answer:

1. Why is title private rather than public?
2. What would a == b print if both came from the same new Book(...) call?
3. Which method reads the title from another class?

Answers: so outside code cannot change it directly; true, both names would point at one object; getTitle().
UP NEXT · MODULE 2
Singleton Classes
45 min · one object, and only one
press ↓ again, or click
Module 2 · Singleton Classes
0%
45 min
next   back   chunk
CHUNK 1 OF 60:00 – 0:05
MODULE 2 · SINGLETON CLASSES · 45 MIN

Why this pattern exists

Module 1 set up the project. This is the first thing built inside it, and it answers a question the language itself cannot: how do you stop a class being made twice?

WITHOUT IT · EVERY CALLER MAKES ITS OWN Order Report Login new Conn() new Conn() new Conn() three connections, three sets of settings WITH IT · ALL THREE SHARE ONE Order Report Login Conn.getInstance() the only one there will ever be one connection, one set of settings a private constructor is what makes the left-hand side impossible
The pattern exists to make the wrong thing unwriteable
Covering the syllabus phrase: Classes and Interfaces — Singleton class
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Before any Java: a classroom has exactly one class monitor at a time. A new monitor cannot be appointed while the post is already filled.

That rule is not about tidiness. It exists because the monitor holds something — today's attendance, who was sent to the office, which period got cancelled. One holder means one answer to any question about it.

Now imagine the post were unguarded and two students each believed they were monitor. Both start taking attendance. Ask "how many present today?" and you get two numbers. Neither is wrong from where that student sits — and there is no way to decide which counts. The information has not just gone stale; it has split.

One monitor — everyone agrees who to ask
vs
Two monitors — nobody knows who's really in charge

The right-hand case is not merely untidy — it is broken, and broken in a way that is hard to notice. Nothing crashes. Both monitors work perfectly. The failure only appears when the two answers are finally compared, which might be days later.

Where this actually bites in real programs

The class monitor is a stand-in for a whole family of real cases. Each one is a thing a program should have exactly one of:

One settings store. Two copies, and a setting changed in one is invisible to the other.
One counter. Two copies, and your total is split across both — each undercounting, neither reporting the truth.
One attendance register. Exactly the classroom case, written in Java instead of on paper.

The pattern you are about to learn is called Singleton — "single" plus "-ton", one instance. Its whole job is to make the second copy impossible, rather than merely discouraged by a comment.

Hold onto that. In a moment you'll watch Java cheerfully create the broken version.

CHUNK 2 OF 6 0:05 – 0:12

What new actually does

Before any code, one rule. It has no exceptions, and the whole module rests on it:

THE RULE
Every time Java meets the word new, it builds a brand-new, separate object. It never checks whether a similar one already exists. It never reuses one.

So if a program says new twice, two objects exist:

Even if they hold identical data — matching contents change nothing.
Even if it makes no sense for the thing being represented.
Even if you did it by accident — Java raises no warning either way.

Apply that to the classroom. A monitor is a post that allows one holder — but Java has no idea about that rule. Ask it for two monitors and it will hand you two, without hesitation.

Watching it happen, one line at a time

Here is the first line. Nothing unusual — this is the ordinary class creation you already know from Unit 1.

ClassMonitor first = new ClassMonitor();
Object 1 is created. Java reserves memory, builds a monitor there, and points the name first at it.
ClassMonitor second = new ClassMonitor();
Object 2 is created. Java does not pause to ask whether a monitor already exists. The rule above applies: new means new.
System.out.println(first == second);
The test. == on two objects asks one narrow question: are these the very same object in memory? Not "do they look alike" — are they the same one?

Now the same three lines, assembled into a program you can actually run.

src / school / ClassMonitor.java
1package school;
2
3public class ClassMonitor
4{
5 public static void main(String[] args)
6 {
7 ClassMonitor first = new ClassMonitor();
8 ClassMonitor second = new ClassMonitor();
9
10 System.out.println("Same monitor? " + (first == second));
11 }
12}
Code on this page can't be copied — type it out. Typing is where it sticks.
Saving is what compiles it. Press Ctrl + S after typing. Eclipse builds the file on every save, so red marks appear immediately — before you ever press Run. Run with the green button or Ctrl + F11.
CONSOLESame monitor? false

No error. No warning. Java did exactly as told and produced two separate monitors. The broken case from the last page is now sitting in front of you, confirmed by that false.

What memory looks like right now

BEFORE THE FIX — EACH new BUILT ITS OWN OBJECT

Two boxes on the left are names. Two boxes on the right are objects. Each name points at its own object — which is exactly why == answered false. Fixing this means making both names point at one object, and that is what the next chunk builds.

CHUNK 3 OF 60:12 – 0:22

Setting up the file in Eclipse

Before writing the fix, the file has to exist in the right place. This is the first file of the unit, so it is worth doing slowly — every later module repeats these same steps without spelling them out.

Java files live inside packages, which are just folders under src. This one goes in a package called school.

1In Package Explorer, right-click the src folder inside Unit2Project
2Choose New → Package, type school, press Finish
3Right-click the new school package, choose New → Class
4Type ClassMonitor as the class name — capital C, capital M, no .java on the end
5Tick public static void main(String[] args) so Eclipse writes the main method for you
6Press Finish. The file opens in the editor, ready to type into
New Java Class
Source folder:
Unit2Project/src
Package:
school
Name:
ClassMonitor
Method stubs:
✓ public static void main(String[] args)
Cancel
Finish

Where it lands

Unit2Project
src
school
ClassMonitor.javanew
The file name must match the class name. A public class ClassMonitor has to sit in ClassMonitor.java. Eclipse handles this when you use the wizard, which is exactly why we use it rather than creating files by hand.
CHUNK 3 OF 6 0:12 – 0:22

Building the fix

Three changes make a second monitor impossible. Not discouraged — impossible, refused by the compiler. They arrive one at a time.

THE PLAN
1. A place to keep the one monitor — a static field.
2. A lock on the door — make the constructor private so no outside code can call new.
3. A single official way in — a static method that hands out that one monitor.
src / school / ClassMonitor.java  — rewritten
1package school;
2
3public class ClassMonitor
4{
5 // 1. the one and only instance lives here
6 private static ClassMonitor theMonitor;
7
8 private String name;
9
10 // 2. private, so no outside code can call new
11 private ClassMonitor()
12 {
13 name = "Asha";
14 System.out.println("A monitor was appointed.");
15 }
16
17 public String getName()
18 {
19 return name;
20 }
21
22 // 3. the single door everyone comes through
23 public static ClassMonitor getInstance()
24 {
25 if (theMonitor == null)
26 {
27 theMonitor = new ClassMonitor();
28 }
29 return theMonitor;
30 }
31}
Console
terminated
<terminated> MonitorDemo [Java Application]
A monitor was appointed.a is Ashab is Ashac is Ashaa == b == c ? true

Run it with the MonitorDemo driver below. The constructor line prints once, not three times — that single line is the proof.

Why each piece is there

private static static means the field belongs to the class itself, not to any object — so there's exactly one of it, no matter what. private stops outside code from reassigning it.
private ClassMonitor() A constructor marked private can only be called from inside this class. Every new ClassMonitor() written anywhere else now fails to compile — that's the lock.
public static getInstance() must be static because you call it without having an object yet — ClassMonitor.getInstance(), not someMonitor.getInstance().
if (… == null) The first call finds nothing and builds it. Every call after that finds it already there and skips straight to the return.

The definition, now that you've built it

The formal definition, which describes exactly what was written above:

A Singleton class is a class that restricts itself to exactly one instance for the lifetime of the program, and provides one shared point of access to that instance.
One word does the work. This constructor is marked private, and that single word is what stops outside code from calling new ClassMonitor(). If you see private on a constructor, a Singleton is almost always the reason.

There is a name for what you just did — hiding the inside of a class and exposing one controlled way in. It is called encapsulation, and Module 7 gives it a section of its own.

Say the three lines out loud

Three unfamiliar words arrive together here. Said in plain English, one at a time, they are simple.

private static ClassMonitor theMonitor;
"Keep one empty slot, and let nobody outside touch it." static means the slot belongs to the class, so there is one slot, not one per object. It starts empty.
private ClassMonitor()
"Lock the front door." The constructor is how objects get made. Marking it private means only code inside this class may make one — nobody else, ever.
public static ClassMonitor getInstance()
"Here is the only way in." A method anyone may call. It looks in the slot: empty, so make one and keep it; already full, so hand back the same one.
IN ONE LINE
One slot · locked door · one official way in. That is the entire pattern — everything else is just Java spelling it out.

If the code still looks dense, read only the three lines above. Nothing else in the class matters to the idea.

The same shape, two places you already know it

The same rule appears outside code. In both cases: one holder of the post, and one route to reach whoever holds it.

A college has exactly one principal
A department has exactly one head (HOD)
the principal Nobody can simply appoint a second principal for the same college — the post allows one holder. Ask the college office who the principal is, and you are pointed to that one person, whoever currently holds it. That office is the getInstance().
the HOD The same shape one level down: one head per department, reached through the department office. Two departments each have their own head — which is exactly why a Singleton is one-per-class, not one-per-program.

Neither needs a line of code to make sense — and that is the point. If you can explain the principal, you can explain getInstance().

CHUNK 4 OF 60:22 – 0:32

Worked example — proving it works

Three separate requests for the monitor, from three different points in main.

src / school / MonitorDemo.java
1package school;
2
3public class MonitorDemo
4{
5 public static void main(String[] args)
6 {
7 ClassMonitor a = ClassMonitor.getInstance();
8 ClassMonitor b = ClassMonitor.getInstance();
9 ClassMonitor c = ClassMonitor.getInstance();
10
11 System.out.println("a is " + a.getName());
12 System.out.println("b is " + b.getName());
13 System.out.println("c is " + c.getName());
14 System.out.println("a == b == c ? " + (a == b && b == c));
15 }
16}
CONSOLE
A monitor was appointed.a is Ashab is Ashac is Ashaa == b == c ? true

The first line printed once, not three times: the constructor ran exactly once across all three requests. That is stronger proof than the boolean alone.

Memory, after the fix

AFTER THE FIX — EVERY REFERENCE POINTS AT THE SAME OBJECT
getInstance()
A
builds it
getInstance()
A
reuses it
getInstance()
A
reuses it

The same object is returned all three times. Writing new ClassMonitor() in this file is rejected by the compiler before the program runs.

IF YOU TRY new ClassMonitor() FROM OUTSIDE
The constructor ClassMonitor() is not visible

Why you'd want this

One source of truth. Every part of the program reads and writes the same object — no disagreement possible.
The rule is enforced, not just requested. The compiler blocks duplication — a comment saying "please don't create two" would not.
Built only when needed. Nothing is created until the first getInstance() call actually asks for it.

Where people slip

Leaving the constructor public. The field and the method are useless if new still works from outside. All three pieces are needed together.
Forgetting static on the field. A non-static field belongs to an object — but you need it before any object exists. It won't compile.
Dropping the null check. Without it, every call builds a fresh object and you're back to the broken version from Chunk 2.
CHUNK 5 OF 60:32 – 0:40

When the one instance gets built

Lazy — what you built built on demand
Eager built upfront

Eager is one line shorter — private static ClassMonitor theMonitor = new ClassMonitor(); and no null check — but it builds the object whether the program ever asks for it or not.

One honest gap in the lazy version
If two parts of the program call getInstance() at the exact same instant, both could find theMonitor still null and both build one. Fixing that needs a tool you meet in Module 12, where this exact class gets its repair.
CHUNK 5 OF 6 · PRACTICE

A second Singleton, different domain

The classroom example made the idea concrete. Here is the same pattern with nothing in common except the shape — a school has one and only one attendance register for the day.

1class AttendanceRegister 2{ 3 private static AttendanceRegister register; 4 private int present; 5 6 private AttendanceRegister() 7 { 8 present = 0; 9 } 10 11 public static AttendanceRegister getInstance() 12 { 13 if (register == null) 14 { 15 register = new AttendanceRegister(); 16 } 17 return register; 18 } 19 20 public void markPresent() 21 { 22 present++; 23 } 24 25 public int getPresent() 26 { 27 return present; 28 } 29}

Two different teachers mark attendance from two different places in the program — and because both reach the same object, the count adds up instead of splitting in two.

1AttendanceRegister t1 = AttendanceRegister.getInstance(); 2AttendanceRegister t2 = AttendanceRegister.getInstance(); 3 4t1.markPresent(); 5t1.markPresent(); 6t2.markPresent(); 7 8System.out.println(t2.getPresent()); // 3, not 1

Same three pieces, different domain. If you can spot the private field, the private constructor and the static access method here, you can spot them anywhere.

PREDICT THE OUTPUT
What does this print, and why?
1AttendanceRegister a = AttendanceRegister.getInstance(); 2a.markPresent(); 3 4AttendanceRegister b = AttendanceRegister.getInstance(); 5b.markPresent(); 6 7System.out.println(a.getPresent() + " " + b.getPresent());
Show the answer
2 2

There is only one register. a and b are two names for the same object, so both increments land on the same counter, and both reads report the same number. Had this been an ordinary class with a public constructor, the answer would have been 1 1 — two separate registers, each counting its own.
FIND THE BUG
This compiles and runs, but it is not a Singleton. What is wrong — and what does the program print?
1class LibraryCard 2{ 3 private static LibraryCard card; 4 5 public LibraryCard() 6 { 7 System.out.println("card created"); 8 } 9 10 public static LibraryCard getInstance() 11 { 12 if (card == null) 13 { 14 card = new LibraryCard(); 15 } 16 return card; 17 } 18} 19 20// elsewhere 21LibraryCard c1 = LibraryCard.getInstance(); 22LibraryCard c2 = new LibraryCard(); 23System.out.println(c1 == c2);
Show the answer
The constructor is public, not private.

Output:
1card created 2card created 3false
getInstance() built the one shared card, and then line two ignored it entirely and built a second card directly. The static field and the access method are doing their jobs perfectly — they are simply being bypassed, because nothing forbids new.

Fix: change public LibraryCard() to private LibraryCard(). The second line then fails to compile with "The constructor LibraryCard() is not visible", which is exactly what you want — the mistake gets caught before the program ever runs.
CHUNK 6 OF 60:40 – 0:45
The exam's word for this: building the object only on the first call is lazy initialization — it waits until someone actually asks. The opposite, eager initialization, builds it the moment the class loads. Lazy saves work; eager needs no synchronized because there is no first-call race.

Exam landing

PYQ · 2 MARKS
"Define a singleton class. Give an example."

Full answer

1
Definition — a Singleton class is one that restricts itself to exactly one instance for the lifetime of the program, and provides a single shared point of access to that instance.
2
How it's achieved — three pieces together: a private static field to hold the one instance, a private constructor so no outside code can call new, and a public static method that creates it on first request and returns the same one thereafter.
3
Example — the complete, runnable program below. Written as one file, it compiles and runs exactly as shown.

The example, written out in full for the answer sheet

SingletonExample.java  — complete and runnable
PART 1 OF 3the class and its private constructor
1class ClassMonitor
2{
3 private static ClassMonitor theMonitor;
4 private String name;
5
6 private ClassMonitor()
7 {
8 name = "Asha";
9 System.out.println("Constructor ran once.");
10 }
11
PART 2 OF 3getInstance() and the getter
12 public static ClassMonitor getInstance()
13 {
14 if (theMonitor == null)
15 {
16 theMonitor = new ClassMonitor();
17 }
18 return theMonitor;
19 }
20
21 public String getName()
22 {
23 return name;
24 }
25}
PART 3 OF 3the driver that proves it
26
27public class SingletonExample
28{
29 public static void main(String[] args)
30 {
31 ClassMonitor m1 = ClassMonitor.getInstance();
32 ClassMonitor m2 = ClassMonitor.getInstance();
33
34 System.out.println("m1 name : " + m1.getName());
35 System.out.println("m2 name : " + m2.getName());
36 System.out.println("Same object? " + (m1 == m2));
37 }
38}
OUTPUT
Constructor ran once.m1 name : Asham2 name : AshaSame object? true

Point out in the answer: "Constructor ran once." appears a single time even though getInstance() was called twice — that one line is what proves only one object was ever created.

Checkpoint

Answer these three, then open the worked answers to check.

1. Remove only the private from the constructor. What breaks?
2. Why must getInstance() be static?
3. Explain the whole pattern to someone in one sentence, using the classroom.

Show worked answers
1. Everything. Outside code can call new ClassMonitor() again, so second and third monitors appear freely — you're back to Chunk 2's false. The field and getInstance() still work, but nothing stops duplication anymore. All three pieces only work together.

2. Because you call it before any object exists. A non-static method needs an object to be called on — but getting that object is the very thing you're calling the method for. static lets you call it on the class itself: ClassMonitor.getInstance().

3. Something like: "The class appoints its own single monitor, refuses to let anyone else appoint one, and hands the same monitor back to everybody who asks."

Project so far

The project after Module 2 — two files: the Singleton class and the driver that demonstrated it.

Unit2Project
  • src
    • school
      • new ClassMonitor.java
      • new MonitorDemo.java

Module 3 adds an abstract class alongside these — nothing here gets replaced.

Practice

Three problems on Singleton. Attempt each one first — solutions are complete and runnable.
1 Write a Singleton PrincipalOffice that stores the principal's name and hands out the same office object every time. Include a small main proving two requests return one object.
Show solution
1class PrincipalOffice 2{ 3 private static PrincipalOffice office; 4 private String principal; 5 6 private PrincipalOffice() 7 { 8 principal = "Dr. Rao"; 9 } 10 11 public static PrincipalOffice getInstance() 12 { 13 if (office == null) 14 { 15 office = new PrincipalOffice(); 16 } 17 return office; 18 } 19 20 public String getPrincipal() 21 { 22 return principal; 23 } 24} 25 26public class OfficeDemo 27{ 28 public static void main(String[] args) 29 { 30 PrincipalOffice o1 = PrincipalOffice.getInstance(); 31 PrincipalOffice o2 = PrincipalOffice.getInstance(); 32 33 System.out.println(o1.getPrincipal()); 34 System.out.println("Same office? " + (o1 == o2)); 35 } 36}
Dr. Rao Same office? true
2 A classmate says: "I made the constructor private, so my class is a Singleton." Is that enough? Explain in two lines, and state what still goes wrong.
Show solution
Not enough. A private constructor only blocks outside creation — it does not create or share an instance. With nothing else, the class becomes unusable: no code anywhere can obtain an object of it at all.

All three pieces are needed together: the private constructor to block new, the private static field to hold the one instance, and the public static method to hand it out.
3 Convert this ordinary class into a Singleton, changing as few lines as possible.
1class ExamSeatPlan 2{ 3 private int totalSeats; 4 5 public ExamSeatPlan() 6 { 7 totalSeats = 120; 8 } 9 10 public int getTotalSeats() 11 { 12 return totalSeats; 13 } 14}
Show solution
Two edits and one addition — three lines in total:
1class ExamSeatPlan 2{ 3 private static ExamSeatPlan plan; // ADDED 4 private int totalSeats; 5 6 private ExamSeatPlan() // public -> private 7 { 8 totalSeats = 120; 9 } 10 11 public static ExamSeatPlan getInstance() // ADDED 12 { 13 if (plan == null) 14 { 15 plan = new ExamSeatPlan(); 16 } 17 return plan; 18 } 19 20 public int getTotalSeats() 21 { 22 return totalSeats; 23 } 24}
Note getTotalSeats() is untouched. Turning a class into a Singleton changes how it is obtained, never what it does.
UP NEXT · MODULE 3
Abstract Classes
45 min · the class that refuses to be built
press ↓ again, or click
Module 3 · Abstract Classes
0%
45 min
next   back   chunk
MODULE 3 · ABSTRACT CLASSES · 45 MIN TOTAL
CHUNK 1 OF 7 0:00 – 0:06

When an unfinished class is the right answer

Module 2 made a class that guards how many objects exist. This one goes further — a class that cannot be made into an object at all, and is still useful.

Covering the syllabus phrase: Classes and Interfaces — Abstract class
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Consider a blueprint that deliberately leaves one room unlabelled. Walls, plumbing and staircase are fixed; the unlabelled room is left for each builder to decide — study, nursery, or storeroom.

THE BLUEPRINT kitchen stairs ? ? ? left undecided Builder A's house → made it a study Builder B's house → made it a nursery Same blueprint. One room, decided differently each time.
THE BLUEPRINT ITSELF IS NEVER A HOUSE — IT IS FINISHED BY WHOEVER BUILDS FROM IT

Why Java needs a keyword for this

You could try to fake it with an ordinary class — write reserve() with an empty body and leave a comment saying "subclasses must override this". Two things go wrong.

A Unit 1 word, recalled: to override a method is for a subclass to write its own version of a method the parent already declared. The subclass's version is the one that runs.

Nothing enforces a comment. A subclass that forgets reserve() compiles happily and silently inherits the empty version. The bug appears at runtime as "nothing happened" — the hardest kind to trace.
The half-finished parent can still be built. Someone writes new Reservation() and gets an object whose central method does nothing — a reservation that cannot reserve.

Marking the class abstract hands both problems to the compiler. The forgetful subclass is refused; the attempt to build the parent is refused. Neither reaches a running program.

abstract method The unlabelled room. Declared but left with no body at all — it ends in a semicolon. Every subclass is forced to supply its own version.
concrete method The kitchen and stairs. Fully written in the class itself, inherited as-is by every subclass — no rewriting needed.
abstract class The blueprint as a whole. Any class holding even one abstract method must itself be marked abstract.
CHUNK 2 OF 7 0:06 – 0:12

What happens if you try to build the blueprint itself

The smallest possible abstract class, followed by the one operation Java refuses to allow.

src / travel / Reservation.java  — read only, cannot run on its own
1package travel;
2
3public abstract class Reservation
4{
5 // no body — every subclass must write its own
6 public abstract void reserve();
7}
Code on this page can't be copied — type it out. Typing is where it sticks.
Saving is what compiles it. Press Ctrl + S after typing. Eclipse builds the file on every save, so red marks appear immediately — before you ever press Run. Run with the green button or Ctrl + F11.

Line 6 is the whole difference: abstract, no braces, ends in a semicolon. A method with no body cannot be run — so an object of this class would be unusable, and Java refuses to make one.

The compiler saying no, in Eclipse

5 {
6 Reservation r = new Reservation();
7 }
Cannot instantiate the type Reservation
Reservation.java · line 6 · Java Problem

Read the message literally: to instantiate is to make an object. Java is stating that this type is not one you can make an object of.

The red mark appears the instant you type it — before you ever press Run. This is a compile-time refusal, not a crash at runtime.

CHUNK 3 OF 7 0:12 – 0:22

Worked example — one abstract, one concrete, two subclasses

Now the useful shape. An abstract class is rarely all holes — that would make it an interface, which Module 5 covers. Its real value is carrying both kinds of method at once.

THE SPLIT
Ask of every method: does every subclass do this identically? If yes, write it once in the parent as a normal method. If each must do it differently, leave it abstract and make them supply it.

Work through the two methods a reservation needs:

1reserve() differs. A train booking allocates a coach and berth; a bus booking allocates a seat number. No sensible shared version exists — so it stays abstract.
2printReceipt() is identical. Every reservation prints the same banner. Writing it twice means fixing any typo twice — so it is written once, concretely, in the parent.

That single judgement is the whole design skill here:

Get it right and every subclass stays short — it writes only what is genuinely its own.
Too much left abstract and subclasses re-implement things they all agree on.
Too much made concrete and a subclass is stuck with behaviour that does not fit it.
src / travel / Reservation.java  — expanded
1package travel;
2
3public abstract class Reservation
4{
5 // DIFFERS per subclass - left abstract
6 public abstract void reserve();
7
8 // SAME for every subclass - written once, here
9 public void printReceipt()
10 {
11 System.out.println("--- Receipt issued ---");
12 }
13
14 // abstract, so it cannot be created directly:
15 // run ReservationDemo instead, which extends this
16 public static void main(String[] args)
17 {
18 Reservation r = new ReserveTrain();
19 r.reserve();
20 r.printReceipt();
21 }
22}
src / travel / ReserveTrain.java
1package travel;
2
3public class ReserveTrain extends Reservation
4{
5 public void reserve()
6 {
7 System.out.println("Train seat booked - coach S4, berth 32");
8 }
9}
src / travel / ReserveBus.java
1package travel;
2
3public class ReserveBus extends Reservation
4{
5 public void reserve()
6 {
7 System.out.println("Bus seat booked - seat 14, window");
8 }
9}
RUNNING BOTH
Train seat booked - coach S4, berth 32--- Receipt issued ---Bus seat booked - seat 14, window--- Receipt issued ---

Each subclass supplied its own reserve(). The receipt line is identical in both, and was written once in the abstract class.

Consider what that buys you. Adding a third booking type — flight, ferry, anything — costs exactly one reserve() method. The receipt, and any shared behaviour added later, arrives free and already correct. That is the return on marking the class abstract.

The hierarchy, drawn

Reservation reserve() ◁ abstract printReceipt() ◁ concrete ReserveTrain reserve() → berth ReserveBus reserve() → seat both inherit printReceipt()
ITALIC NAME MEANS ABSTRACT — THE ARROW HEAD POINTS AT THE PARENT
Forget to write reserve() in a subclass and that subclass won't compile either — Java makes you either implement it or declare the subclass abstract too.
CHUNK 4 OF 7 0:22 – 0:29

Can an abstract class have a constructor?

It sounds contradictory, since no object of the class can be made directly. Yet an abstract class can have a constructor, and it does run.

src / travel / Reservation.java  — with a constructor
1package travel;
2
3public abstract class Reservation
4{
5 String pnr;
6
7 Reservation()
8 {
9 pnr = "PNR-4417";
10 System.out.println("Reservation constructor ran.");
11 }
12
13 public abstract void reserve();
14
15 public static void main(String[] args)
16 {
17 Reservation r = new ReserveTrain();
18 System.out.println("PNR is " + r.pnr);
19 }
20}
Console
terminated
<terminated> ReservationDemo [Java Application]
Cannot instantiate the type Reservation

This class alone produces no output — it cannot be run. Attempting new Reservation() gives the compiler error above, which is the whole point of Chunk 2.

src / travel / ConstructorDemo.java
1package travel;
2
3public class ConstructorDemo
4{
5 public static void main(String[] args)
6 {
7 ReserveTrain t = new ReserveTrain();
8 System.out.println("PNR is " + t.pnr);
9 }
10}
CONSOLE
Reservation constructor ran.PNR is PNR-4417

No code wrote new Reservation(). Its constructor still ran, and the field it initialised is present inside the ReserveTrain object.

why it ran Every subclass constructor begins with a call to its parent's constructor. If you don't write one, Java inserts a no-argument call automatically. Building a ReserveTrain therefore always builds its Reservation part first.
what it's for Shared setup. Fields common to every reservation — a PNR, a timestamp, a passenger name — get initialised once here instead of being repeated in every subclass.
no access word The field is written plainly, with no public or private in front. That is enough for a subclass in the same package to read it. Access specifiers get their own full treatment in Module 7.

Note there is no super() written anywhere above — none is needed, so none was added.

CHUNK 5 OF 7 0:29 – 0:34

Why reach for one — and when not to

Shared code written once. printReceipt() lives in one place. Fix a typo there and every subclass is fixed at the same time.
Shared state, initialised once. The constructor sets up fields every subclass needs, without each one repeating that work.
The gap is enforced. A subclass cannot quietly forget reserve() — the compiler stops it. A comment asking politely would not.
One type covers all of them. A Reservation variable can hold a train or a bus booking, so code that handles bookings doesn't care which kind arrived.

Abstract class or plain superclass?

Plain superclass
Abstract class
Can you make an object of it?
Yes
No — compiler blocks it
Can it force subclasses to write a method?
No
Yes — that's the point
Can it hold shared, finished code?
Yes
Yes
Reach for it when…
the parent is a usable thing in its own right
the parent is only ever a starting point, never a finished thing
In our code
Reservation — no sensible default reserve() exists
A Vehicle whose start() every subclass inherits unchanged

The deciding question is simply: does a plain "Reservation" — neither train nor bus — mean anything on its own? It doesn't. That's the signal to make it abstract.

CHUNK 5 OF 7 · PRACTICE

A second abstract class, nothing to do with travel

Same shape, different subject. Every exam paper has to be graded, but a multiple-choice paper and a written paper are graded in completely different ways — while the pass mark is identical for both.

1abstract class ExamPaper 2{ 3 // differs per paper type 4 public abstract int grade(); 5 6 // identical for every paper type 7 public boolean hasPassed(int marks) 8 { 9 return marks >= 40; 10 } 11} 12 13class MCQPaper extends ExamPaper 14{ 15 public int grade() 16 { 17 System.out.println("Grading by answer key"); 18 return 72; 19 } 20} 21 22class WrittenPaper extends ExamPaper 23{ 24 public int grade() 25 { 26 System.out.println("Grading by examiner rubric"); 27 return 35; 28 } 29}

Both papers are graded through one common variable type, and both use the same untouched hasPassed().

1ExamPaper p1 = new MCQPaper(); 2ExamPaper p2 = new WrittenPaper(); 3 4int m1 = p1.grade(); 5int m2 = p2.grade(); 6 7System.out.println(p1.hasPassed(m1)); 8System.out.println(p2.hasPassed(m2));
Grading by answer key Grading by examiner rubric true false
PREDICT THE OUTPUT
Both variables are declared as ExamPaper. What prints, and which grade() actually runs?
1ExamPaper p1 = new WrittenPaper(); 2ExamPaper p2 = new MCQPaper(); 3 4int m1 = p1.grade(); 5System.out.println(p1.hasPassed(m1)); 6 7int m2 = p2.grade(); 8System.out.println(p2.hasPassed(m2));
Show the answer
1Grading by examiner rubric 2false 3Grading by answer key 4true
Both variables are declared as ExamPaper, the parent type — but each object remembers what it really is. Java picks grade() based on the actual object, not the declared type — so the written paper grades by rubric and the MCQ by key. hasPassed() is not overridden anywhere, so both calls run the one version in ExamPaper.

This is why the abstract class earns its place: the same two lines handle both paper types, with no if checking which kind you have.
FIND THE BUG — two of them
Neither of these compiles. Name the error Eclipse shows for each.
1// A 2class PracticalPaper extends ExamPaper 3{ 4 public boolean hasPassed(int marks) 5 { 6 return marks >= 50; 7 } 8} 9 10// B 11ExamPaper p = new ExamPaper();
Show the answer
A — "The type PracticalPaper must implement the inherited abstract method ExamPaper.grade()"
It overrode hasPassed(), which it was free to do but was never required to. It never supplied grade(), which it was required to. Overriding an optional method does not satisfy a mandatory one.

B — "Cannot instantiate the type ExamPaper"
The same refusal from Chunk 2. grade() has no body, so an ExamPaper object would have a method that cannot run — Java refuses to create one.

Fixing A: add a grade() method to PracticalPaper, or mark the class abstract itself and let its own subclasses supply it.
CHUNK 6 OF 7 0:34 – 0:41
Three formal names for what you just did. A subclass writing its own version of a parent's method is method overriding. Storing a ReserveTrain in a Reservation variable is upcasting. Java choosing which reserve() runs at run time, based on the real object rather than the variable's type, is dynamic method dispatch — also called run-time polymorphism.

Exam landing

PYQ · 4 MARKS
"Design an abstract class Reservation containing an abstract method reserve(). Implement this class through two subclasses, ReserveTrain and ReserveBus, each providing its own implementation of reserve()."

How to structure the answer

1
The abstract class — Reservation, marked abstract, declaring reserve() with no body.
2
Two subclasses — each extends Reservation and supplies its own reserve().
3
A driver — creates one of each and calls reserve(), proving the two behave differently from the same parent type.

The complete program for the answer sheet

ReservationDemo.java  — complete and runnable
PART 1 OF 3the abstract parent
1abstract class Reservation
2{
3 public abstract void reserve();
4
5 public void printReceipt()
6 {
7 System.out.println("--- Receipt issued ---");
8 }
9}
10
PART 2 OF 3the two subclasses
11class ReserveTrain extends Reservation
12{
13 public void reserve()
14 {
15 System.out.println("Train reserved : coach S4, berth 32");
16 }
17}
18
19class ReserveBus extends Reservation
20{
21 public void reserve()
22 {
23 System.out.println("Bus reserved : seat 14, window");
24 }
25}
26
PART 3 OF 3the driver and its output
27public class ReservationDemo
28{
29 public static void main(String[] args)
30 {
31 Reservation r1 = new ReserveTrain();
32 Reservation r2 = new ReserveBus();
33
34 r1.reserve();
35 r1.printReceipt();
36
37 r2.reserve();
38 r2.printReceipt();
39 }
40}
OUTPUT
Train reserved : coach S4, berth 32--- Receipt issued ---Bus reserved : seat 14, window--- Receipt issued ---

Worth two extra marks: lines 31–32 declare both variables as type Reservation, not ReserveTrain/ReserveBus. Java still calls the right reserve() for each. Say so in the answer — it shows the abstract class is doing real work as a shared type, not just holding a method signature.

CHUNK 7 OF 7 0:41 – 0:45

Checkpoint — add a third subclass

Write ReserveFlight extending the same Reservation class, then answer both questions before opening the solution.

1. Write the full ReserveFlight class.
2. Do you have to write printReceipt() in it? Why or why not?
3. If you only wrote the class header and left the body empty, what would Eclipse say?

Show worked solution
1. Same shape as the other two:
class ReserveFlight extends Reservation { public void reserve() { System.out.println("Flight reserved : 6E-233, seat 22A"); } } 2. No. printReceipt() is concrete in Reservation, so it's inherited already — writing it again would only duplicate working code. Only reserve() is left unfinished, so only reserve() must be supplied.

3. "The type ReserveFlight must implement the inherited abstract method Reservation.reserve()" — the same compile-time refusal from Chunk 2, arriving for the opposite reason: there, you tried to build something unfinished; here, you left something unfinished.

Project so far

Three files added this module, in a new travel package alongside the existing school package.

Unit2Project
  • src
    • school
      • module 2 ClassMonitor.java
      • module 2 MonitorDemo.java
    • travel
      • new Reservation.java
      • new ReserveTrain.java
      • new ReserveBus.java

Module 4 adds nested classes to this same tree — nothing here gets replaced.

Practice

Three problems on abstract classes. Attempt each before opening the solution.
1 Design an abstract Employee with an abstract calculateSalary() and a concrete showId(). Implement PermanentEmployee and ContractEmployee, then create one of each and print both salaries.
Show solution
1Employee e1 = new PermanentEmployee(); 2Employee e2 = new ContractEmployee(); 3 4e1.showId(); 5System.out.println("Salary : " + e1.calculateSalary()); 6 7e2.showId(); 8System.out.println("Salary : " + e2.calculateSalary());
Employee ID : 101 Salary : 50000.0 Employee ID : 202 Salary : 19800.0
Each subclass sets id directly in its own constructor. No super() is written anywhere, because none is needed — the parent has a no-argument constructor, so Java supplies that call itself.
2 Can an abstract class have no abstract methods at all? If yes, what does marking it abstract still achieve?
Show solution
Yes, that is legal. A class can be marked abstract with every method fully written.

What it still achieves: nobody can create an object of it directly. It becomes a base that must be extended before it can be used. This is occasionally useful for a class that holds shared setup but has no meaning as a standalone thing.

The reverse is not legal — a class containing even one abstract method must itself be declared abstract.
3 Predict the output, then explain which constructor runs first and why.
1abstract class Vehicle 2{ 3 Vehicle() 4 { 5 System.out.println("Vehicle ready"); 6 } 7 8 public abstract void start(); 9} 10 11class Car extends Vehicle 12{ 13 Car() 14 { 15 System.out.println("Car ready"); 16 } 17 18 public void start() 19 { 20 System.out.println("Car started"); 21 } 22} 23 24// in main 25Vehicle v = new Car(); 26v.start();
Show solution
Vehicle ready Car ready Car started
The parent constructor runs first. Every subclass constructor begins with a call to its parent's constructor; since none was written here, Java inserts a no-argument call automatically. So building a Car builds its Vehicle part first, then finishes the Car part.

Note also that v is declared as Vehicle, yet v.start() runs Car's version — Java selects the method from the actual object, not the declared type.
UP NEXT · MODULE 4
Nested & Inner Classes
45 min · static nested, inner, anonymous
press ↓ again, or click
Module 4 · Nested & Inner Classes
0%
45 min
next   back   chunk
MODULE 4 · NESTED & INNER CLASSES · 45 MIN TOTAL
CHUNK 1 OF 6 0:00 – 0:07

A class that only makes sense inside another

Module 3 left a class deliberately unfinished. This one is deliberately hidden — a class that only makes sense inside another.

Covering the syllabus phrase: Classes and Interfaces — Nested class
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Some things have no meaning on their own. A car's engine is a real, complicated thing — but nobody keeps a spare engine in the living room and calls it useful. It exists to sit inside a car.

Java lets you write a class in exactly that position: declared inside another class, because outside it the class would mean nothing.

outer class The whole thing — the car. It is an ordinary class in every way, saved in its own .java file.
nested class A class written inside the outer class's braces. It does not get its own file. Its full name includes the outer class: Car.Engine.
why bother It keeps the helper next to the only code that uses it, and it makes the relationship obvious to anyone reading — no hunting through fifteen files to learn that Engine belongs to Car.

Java offers four forms of this. The three you will meet and be examined on:

Static nested — grouped under the outer class for tidiness. Needs no outer object.
Inner — tied to one particular outer object, and able to read its private data.
Anonymous — written and used in a single place, never given a name.
CHUNK 2 OF 6 0:07 – 0:16

Static nested class

Marked static. It lives inside the outer class for organisation only — it does not need an outer object to exist, and it cannot reach the outer object's fields.

THE TEST
Does this helper need to read data belonging to a particular outer object? If no, make it static. The nesting is then purely organisational — a filing decision, not a behavioural one.

A college address is a good fit. The address does not depend on which college object you happen to hold; it is data in its own right. Nesting it under College just says "this belongs to the college concept" so nobody has to hunt for a loose Address.java among forty files.

Creating the file in Eclipse

A nested class needs no new file. It is typed inside the braces of the class that contains it.

1Right-click src, choose New → Package, name it campus
2Right-click campus, choose New → Class, name it College
3Type the Address class inside College's braces — do not create a second file
4Save with Ctrl+S. Package Explorer still shows one file; expand it to see Address listed underneath
campus
College.java
Addressnested, same file
src / campus / College.java
1package campus;
2
3public class College
4{
5 private String name = "Vasavi";
6
7 static class Address
8 {
9 private String city = "Hyderabad";
10
11 void show()
12 {
13 System.out.println("City : " + city);
14 }
15 }
16}
17
18class NestedDemo
19{
20 public static void main(String[] args)
21 {
22 new College.Address().show();
23 }
24}
Saving is what compiles it. Press Ctrl + S after typing. Eclipse builds the file on every save, so red marks appear immediately — before you ever press Run. Run with the green button or Ctrl + F11.

Worked example — creating one

src / campus / StaticNestedDemo.java
1package campus;
2
3public class StaticNestedDemo
4{
5 public static void main(String[] args)
6 {
7 // no College object needed anywhere
8 College.Address a = new College.Address();
9 a.show();
10 }
11}
CONSOLECity : Hyderabad

Line 8 is the whole syntax: Outer.Inner obj = new Outer.Inner(); — the outer class name appears, but no outer object is ever built.

It cannot touch name. Writing System.out.println(name); inside Address fails with "Cannot make a static reference to the non-static field name". A static nested class has no outer object to read that field from.
CHUNK 3 OF 6 0:16 – 0:26

Inner class — the non-static one

Drop the static and everything changes. The class is now tied to a specific outer object, and in exchange it can read that object's private fields directly.

That trade is worth being precise about, because it is the whole difference between the two forms:

You give up
You gain
Cost
Independence — it cannot exist alone
Direct access to the outer object's private data, no getters needed
Every inner object silently carries a reference to its outer object

A principal is the natural example, and it shows why the dependency is worth modelling:

"The principal" means nothing alone — the principal of what?
The post exists only relative to a college, so the object should too.
It naturally needs that college's details, which is exactly what an inner class gives it.
src / campus / College.java  — inner class added
1public class College
2{
3 private String name = "Vasavi";
4
5 // no static keyword this time
6 class Principal
7 {
8 void introduce()
9 {
10 // reads the outer object's private field directly
11 System.out.println("Principal of " + name);
12 }
13 }
14
15 public static void main(String[] args)
16 {
17 College c = new College();
18 College.Principal p = c.new Principal();
19 p.introduce();
20 }
21}

Worked example — creating one needs an outer object first

src / campus / InnerDemo.java
1public class InnerDemo
2{
3 public static void main(String[] args)
4 {
5 College c = new College();
6
7 // note the unusual syntax: c.new
8 College.Principal p = c.new Principal();
9 p.introduce();
10 }
11}
CONSOLEPrincipal of Vasavi

Line 8 is the syntax students most often get wrong, and the one that makes this topic feel hard: c.new Principal().

READ IT BACKWARDS
Do not read it as "c dot new". Read it as: "ask c to make me a Principal." The college makes its own principal, so the college's name goes first.
Ordinary class: new Principal() — "make me a principal." Java asks: of which college? and has no answer.
Inner class: c.new Principal() — "college c, make your principal." Now there is an answer, so the object can exist.
That is the only new syntax in this module. Everything else is ordinary Java you have already written.

It looks strange because it is rare — most Java code never needs it. You need to recognise it and be able to write it once; you do not need to find it natural.

What that link looks like in memory

College object name = "Vasavi" created first, by new College() holds a link back Principal object can read name through that link — no getter needed built by c.new Principal()
EVERY INNER OBJECT CARRIES A HIDDEN REFERENCE TO THE OUTER OBJECT THAT MADE IT
Writing new College.Principal() fails with "An enclosing instance that contains College.Principal is required" — Java is telling you it has no outer object to attach the new inner object to.
CHUNK 4 OF 6 0:26 – 0:34

Anonymous inner class

Start from a question: if a class is going to be written, used once, and never mentioned again — why give it a name at all?

Here is the long way. An interface, a named class implementing it, and one use:

the long way — two files for one message
1interface Greeting
2{
3 void greet();
4}
5
6class MorningGreeting implements Greeting
7{
8 public void greet()
9 {
10 System.out.println("Good morning");
11 }
12}
13
14public class GreetDemo
15{
16 public static void main(String[] args)
17 {
18 Greeting g = new MorningGreeting();
19 g.greet();
20 }
21}

The name MorningGreeting is used exactly once, on line 14, and never again. An anonymous inner class removes it:

src / campus / AnonDemo.java
PART 1 OF 2the interface it implements
1interface Greeting
2{
3 void greet();
4}
5
PART 2 OF 2the nameless class, written inline
6public class AnonDemo
7{
8 public static void main(String[] args)
9 {
10 Greeting g = new Greeting()
11 {
12 public void greet()
13 {
14 System.out.println("Good morning");
15 }
16 };
17
18 g.greet();
19 }
20}
CONSOLEGood morning
new Greeting() Reads like creating an interface object, which is impossible. It is not — it means "make a nameless class that implements Greeting, and give me one object of it".
{ … } The body of that nameless class, opening immediately after the brackets. Everything the class contains goes in here.
}; Line 16 — the semicolon that catches everyone. This is still an assignment statement, so it must be terminated, unlike a normal class's closing brace.
CHUNK 5 OF 6 0:34 – 0:40

Why nest a class at all

Every nested class could have been an ordinary class in its own file. These are the reasons not to.

The relationship becomes visible. Seeing Address inside College tells you instantly that it belongs there. A loose Address.java among forty files tells you nothing.
The helper stops leaking outward. A nested class can be kept invisible to the rest of the program, so nothing else starts depending on a type meant for one job.
Inner classes reach data without plumbing. Principal reads name directly. Written separately it would need the college passed in, stored, and exposed by a getter — three more pieces to keep correct.
Anonymous classes remove dead names. A class used once needs no name, no file, and no place in your mental index of the project.
WHEN NOT TO
If the helper is useful to more than one outer class, or is likely to grow, give it its own file. Nesting suits parts that only make sense inside one thing — nest something reusable and you have hidden it from the code that needs it.

All three, side by side

Static nested
Inner
Declared as
static class X
class X
Needs an outer object?
No
Yes — always
Created by
new Outer.X()
outerObj.new X()
Can read outer's fields?
No
Yes, even private ones
Reach for it when
the helper is just grouped under the outer class for tidiness
the helper genuinely needs the outer object's data
In our code
College.Address
c.new Principal()
AnonDemo’s one-off Greeter
STATIC NESTED College (class) no object needed Address stands alone new College.Address() INNER College object must exist first Principal tied to that college c.new Principal() ANONYMOUS Greeting (interface) the shape to fill (no name) used once, here new Greeting() { ... };
SOLID BOX = THE CLASS ITSELF · FILLED BOX = WHAT YOU GET · DASHED = NEVER NAMED
Anonymous
Declared and created in a single expression, with no name at all. Needs an interface or class to extend. Used once, right where it is written.
Choosing between them
Will you refer to this class by name more than once? If yes, it needs a name — static nested or inner. If it is a one-off, make it anonymous.
PREDICT THE OUTPUT
Two inner objects are made from two different outer objects. What prints?
1class Batch 2{ 3 private int year; 4 5 Batch(int y) 6 { 7 year = y; 8 } 9 10 class Section 11 { 12 void show() 13 { 14 System.out.println("Section of " + year); 15 } 16 } 17} 18 19Batch b1 = new Batch(2024); 20Batch b2 = new Batch(2025); 21 22b1.new Section().show(); 23b2.new Section().show();
Show the answer
Section of 2024 Section of 2025
Each Section object is bound to the particular Batch that created it, so each reads a different year. This is the whole point of an inner class — the same class definition produces objects that behave differently depending on which outer object they belong to.
FIND THE BUG — two of them
Neither line compiles. Name the error for each.
1// A 2Batch.Section s = new Batch.Section(); 3 4// B — inside the static nested Address class 5void show() 6{ 7 System.out.println(name); 8}
Show the answer
A — "An enclosing instance that contains Batch.Section is required"
Section is an inner class, so it cannot exist without a Batch object. Fix: Batch b = new Batch(2024); Batch.Section s = b.new Section();

B — "Cannot make a static reference to the non-static field name"
Address is static, so there is no outer object for it to read name from. Fix: either drop static to make it an inner class, or pass the name in as a parameter.
CHUNK 6 OF 6 0:40 – 0:45

Checkpoint — pick the right form

Three scenarios. For each, say which of the three forms fits and give one line of reasoning.

1. A BankAccount class needs a small Transaction type that records an amount and a date. Transactions are created and listed from many places in the program.
2. A Library class needs a DueDateCalculator that must read the library's own loanPeriodDays field.
3. A button needs a click handler that prints one line, used at exactly one place in the code.

Show worked solution
1. Static nested. A Transaction has its own amount and date — it never needs to read the account's fields. Grouping it under BankAccount shows the relationship, and static means callers can build one with new BankAccount.Transaction(...) without holding an account object.

2. Inner. It must reach loanPeriodDays on a specific library object. Making it static would break exactly that — "Cannot make a static reference to the non-static field". Create it with lib.new DueDateCalculator().

3. Anonymous. One use, one place, no name needed anywhere else. Written inline as new ClickHandler() { ... }; — remember the semicolon after the closing brace.

Practice

Three problems

Attempt each before opening the solution.
1 Write a Laptop class with an inner Battery class that prints the laptop's model along with a charge percentage. Drive it from main.
Show solution
1class Laptop 2{ 3 private String model = "ThinkPad X1"; 4 5 class Battery 6 { 7 private int charge = 82; 8 9 void status() 10 { 11 System.out.println(model + " battery : " + charge + "%"); 12 } 13 } 14} 15 16public class LaptopDemo 17{ 18 public static void main(String[] args) 19 { 20 Laptop l = new Laptop(); 21 Laptop.Battery b = l.new Battery(); 22 b.status(); 23 } 24}
ThinkPad X1 battery : 82%
Battery reads model with no getter, because an inner object holds a link to the outer object that made it.
2 Rewrite this named class as an anonymous inner class at its point of use.
1interface Alarm 2{ 3 void ring(); 4} 5 6class LoudAlarm implements Alarm 7{ 8 public void ring() 9 { 10 System.out.println("Wake up"); 11 } 12} 13 14Alarm a = new LoudAlarm(); 15a.ring();
Show solution
1interface Alarm 2{ 3 void ring(); 4} 5 6Alarm a = new Alarm() 7{ 8 public void ring() 9 { 10 System.out.println("Wake up"); 11 } 12}; 13 14a.ring();
The LoudAlarm class disappears entirely. Watch the semicolon after the closing brace — the whole thing is still one assignment statement.
3 Explain in two lines why outerObj.new Inner() exists as syntax at all. Why can Java not simply use new Outer.Inner() for both forms?
Show solution
An inner object needs to know which outer object it belongs to, and that information has to come from somewhere. Putting the outer object on the left of new is how you supply it.

new Outer.Inner() names only the class, not any particular object — which is exactly enough for a static nested class, and exactly not enough for an inner one. The two syntaxes exist because the two forms need different amounts of information.

Project so far

Unit2Project
  • src
    • m2 school / ClassMonitor.java
    • m2 school / MonitorDemo.java
    • m3 travel / Reservation.java
    • m3 travel / ReserveTrain.java
    • m3 travel / ReserveBus.java
    • campus
      • new College.java
      • new StaticNestedDemo.java
      • new InnerDemo.java
      • new AnonDemo.java

Module 5 adds interfaces to this same tree — nothing here gets replaced.

UP NEXT · MODULE 5
Interfaces
45 min · the contract several classes can sign
press ↓ again, or click
Module 5 · Interfaces
0%
45 min
next   back   chunk
MODULE 5 · INTERFACES · 45 MIN TOTAL
CHUNK 1 OF 7 0:00 – 0:07

An agreement anyone can sign

Covering the syllabus phrase: Classes and Interfaces — Interface
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

A hospital, a school and a shopping mall have nothing in common. Different buildings, different staff, different purpose.

Yet all three sign the same fire-safety agreement: there must be an alarm, an exit route, and a drill schedule. The agreement says what each building must provide. It says nothing about how — the mall's alarm and the school's alarm can work completely differently.

FireSafety soundAlarm(); showExit(); the agreement — no bodies, only names Hospital silent alarm to staff pagers School bell + corridor announcement Mall sirens on every floor
ONE AGREEMENT · THREE UNRELATED SIGNERS · THREE DIFFERENT IMPLEMENTATIONS
interface A list of method names with no bodies at all. It is a promise about what will exist, never about how it works.
implements The keyword a class uses to sign the agreement. Having signed, it must supply every method the interface named — the compiler checks.
no state An interface holds no ordinary fields. It describes behaviour only, which is exactly why unrelated classes can all sign it without conflict.
CHUNK 2 OF 7 0:07 – 0:15

The smallest working example

Two files. The first states what must exist; the second supplies it. Neither knows anything about the other beyond that agreement.

THE SHAPE
An interface method has no body and no braces — it ends in a semicolon. That is not a shorthand; it is the point. A body would be a decision about how, and the interface deliberately refuses to make that decision.
src / safety / FireSafety.java
1package safety;
2
3public interface FireSafety
4{
5 // no body, no braces — just a promise
6 void soundAlarm();
7}
src / safety / School.java
1package safety;
2
3public class School implements FireSafety
4{
5 public void soundAlarm()
6 {
7 System.out.println("Bell + corridor announcement");
8 }
9}
10
11class SafetyDemo
12{
13 public static void main(String[] args)
14 {
15 new School().soundAlarm();
16 }
17}
Saving is what compiles it. Press Ctrl + S after typing. Eclipse builds the file on every save, so red marks appear immediately — before you ever press Run. Run with the green button or Ctrl + F11.
CONSOLEBell + corridor announcement
public is not optional on line 5. Interface methods are public by default, and a class may never reduce that. Leave it off and you get "Cannot reduce the visibility of the inherited method".
Skip soundAlarm() entirely and the class will not compile: "The type School must implement the inherited abstract method FireSafety.soundAlarm()" — the same enforcement you met with abstract classes in Module 3.
CHUNK 3 OF 7 0:15 – 0:24

Signing more than one agreement

A class may extend only one class. That is a hard limit in Java, and it is worth knowing why — because that limitation is the entire reason interfaces exist.

Why Java allows only one parent class

Suppose a class could extend two parents, and both happened to define a method called report(), each with its own body. A call to report() on the child would have two candidates and no rule for choosing. Worse, if both parents held a field called count, the child would carry two different counts under one name.

Languages that permit two parents need complicated rules to untangle it. Java forbids it instead:

One parent — so there is only ever one inherited body for any method.
One set of fields — no name carrying two different values.
No ambiguity to resolve — and so no rules to learn for resolving it.
THE ESCAPE
The ambiguity only arises because a parent class carries bodies and state. An interface carries neither — only names. Two interfaces declaring report() create no conflict, because neither supplies an implementation to choose between. So a class may sign as many as it needs.

That is the trade in one line: one class for what you inherit, many interfaces for what you promise.

src / safety / Accessible.java
1package safety;
2
3public interface Accessible
4{
5 void rampAvailable();
6}
src / safety / Hospital.java
1package safety;
2
3public class Hospital implements FireSafety, Accessible
4{
5 public void soundAlarm()
6 {
7 System.out.println("Silent alarm to staff pagers");
8 }
9
10 public void rampAvailable()
11 {
12 System.out.println("Ramp at every entrance");
13 }
14}
15
16class BothDemo
17{
18 public static void main(String[] args)
19 {
20 Hospital hos = new Hospital();
21 hos.soundAlarm(); // from FireSafety
22 hos.rampAvailable(); // from Accessible
23 }
24}
CONSOLESilent alarm to staff pagersRamp at every entrance

One comma on line 3 of Hospital.java is the whole syntax. Both agreements are now binding, and both methods had to be supplied.

CHUNK 4 OF 7 0:24 – 0:31

Two newer additions: default and static

Originally an interface could hold nothing but empty method names. That caused a practical problem: add one new method to an interface, and every class that ever signed it stops compiling until it supplies that method too.

Java 8 added two escapes, and both exist for practical reasons rather than elegance.

Picture an interface used by two hundred classes across a codebase you don't fully control. Adding one method the old way breaks all two hundred at once, and every owner must be found and made to fix theirs before anything compiles again. That cost meant interfaces effectively could never grow.

src / safety / FireSafety.java  — with both forms
1package safety;
2
3public interface FireSafety
4{
5 void soundAlarm();
6
7 // has a body - signers inherit it, may override
8 default void showExit()
9 {
10 System.out.println("Follow the green exit signs");
11 }
12
13 // called on the interface itself, not on any object
14 static String helpline()
15 {
16 return "101";
17 }
18}
19
20class FormsDemo
21{
22 public static void main(String[] args)
23 {
24 System.out.println("Helpline: " + FireSafety.helpline());
25
26 School s = new School();
27 s.soundAlarm(); // the school wrote its own
28 s.showExit(); // inherited from the interface
29 }
30}
using them — read only, lines lifted from a larger main
1School s = new School();
2s.soundAlarm();
3s.showExit(); // inherited, School wrote nothing
4
5System.out.println(FireSafety.helpline());
CONSOLEBell + corridor announcementFollow the green exit signs101
default A ready-made implementation every signer receives free. Add one to a live interface and nothing breaks — existing classes keep compiling. A class may still override it if the default does not suit.
static A helper belonging to the interface itself. Called as FireSafety.helpline(), never through an object, and never inherited by signers.
CHUNK 5 OF 7 0:31 – 0:38
Why Java has interfaces at all. Some languages let a class have two parents — multiple inheritance — which creates the problem of which parent wins when both define the same method. Java refuses, allowing one parent only, and gives interfaces instead: many contracts, no competing implementations to choose between.

Exam landing

PYQ · 4 MARKS
"Design an interface Library with methods drawBook(), returnBook(), and checkStatus(). Implement this interface through a class VasaviLibrary."
«interface» Library drawBook() returnBook() checkStatus() VasaviLibrary supplies a real body for all three dashed arrow + hollow head means "implements"
DRAW THIS IN THE ANSWER — IT EARNS MARKS ON ITS OWN

Setting it up in Eclipse

All three classes go in a single file here, which is legal as long as only one of them is public — and that one must match the file name.

1Right-click srcNew → Package, name it safety
2Right-click safetyNew → Class, name it LibraryDemo, tick the main stub
3Type the Library interface and VasaviLibrary class above the public class, in the same file
4Save, then run with Ctrl+F11
In the exam, write all three in one answer. You are not being marked on file organisation — you are being marked on the interface, the implementing class, and a driver that proves it runs.
LibraryDemo.java  — complete and runnable
PART 1 OF 3the interface
1interface Library
2{
3 void drawBook(String title);
4 void returnBook(String title);
5 void checkStatus();
6}
PART 2 OF 3the class that implements it
7class VasaviLibrary implements Library
8{
9 private int booksIssued = 0;
10
11 public void drawBook(String title)
12 {
13 booksIssued++;
14 System.out.println("Issued : " + title);
15 }
16
17 public void returnBook(String title)
18 {
19 booksIssued--;
20 System.out.println("Returned : " + title);
21 }
22
23 public void checkStatus()
24 {
25 System.out.println("Books currently out : " + booksIssued);
26 }
27}
PART 3 OF 3the driver
28public class LibraryDemo
29{
30 public static void main(String[] args)
31 {
32 Library lib = new VasaviLibrary();
33
34 lib.drawBook("Let Us C");
35 lib.drawBook("Core Java");
36 lib.checkStatus();
37
38 lib.returnBook("Let Us C");
39 lib.checkStatus();
40 }
41}
OUTPUT Issued : Let Us CIssued : Core JavaBooks currently out : 2Returned : Let Us CBooks currently out : 1

Worth a mark: line 32 declares lib as type Library, the interface — not VasaviLibrary. Say in the answer that an interface can be used as a variable type even though it can never be instantiated.

CHUNK 6 OF 7 0:38 – 0:42

Why interfaces are worth the extra file

An interface costs a file and a keyword. What it buys back:

Unrelated classes gain a shared type. A hospital and a mall have no common parent, yet both can be held in a FireSafety variable and treated identically.
The single-parent limit stops hurting. A class already extending something can still promise any number of capabilities.
Code depends on the promise, not the class. A method taking a Library works with VasaviLibrary, or any library written later that you have never seen.
The compiler enforces the contract. A signer that forgets a method fails to compile — the agreement cannot be quietly broken.
WHEN TO REACH FOR ONE
When you are describing a capability rather than a kind of thing. "Can be played", "can be printed", "can sound an alarm" — all interfaces. "Is a kind of reservation" is an abstract class.

Interface vs abstract class

This comparison is asked directly in exams. Both enforce that subclasses supply certain methods — the differences are what decide which you reach for.

Abstract class
Interface
How many can a class take?
One only
As many as needed
Keyword used
extends
implements
Can hold ordinary fields?
Yes — shared state
No — behaviour only
Can hold finished methods?
Yes
Only as default or static
Can have a constructor?
Yes — runs for subclasses
No
Relationship it expresses
"is a kind of"
"is capable of"
Reach for it when
related classes share state and code
unrelated classes share only a capability
In our code
Library — three promises, no shared code
ReservationprintReceipt() shared, reserve() not

The quickest test: could two totally unrelated classes need this? A hospital and a mall are not kinds of the same thing, but both are capable of fire safety — so that is an interface. A train booking and a bus booking are both kinds of reservation, sharing a PNR and a receipt — so that was an abstract class.

PREDICT THE OUTPUT
The class overrides one default method but not the other. What prints?
1interface Printer 2{ 3 default void header() 4 { 5 System.out.println("--- default header ---"); 6 } 7 8 default void footer() 9 { 10 System.out.println("--- default footer ---"); 11 } 12} 13 14class Receipt implements Printer 15{ 16 public void header() 17 { 18 System.out.println("VASAVI STORE"); 19 } 20} 21 22Receipt r = new Receipt(); 23r.header(); 24r.footer();
Show the answer
VASAVI STORE --- default footer ---
Receipt overrode header(), so its own version runs. It said nothing about footer(), so the interface's default body runs untouched. The class compiled without supplying either — that is exactly what default is for.
FIND THE BUG — three of them
Name the error for each line.
1// A 2interface Payable 3{ 4 private int amount = 500; 5 void pay(); 6} 7 8// B 9Payable p = new Payable(); 10 11// C 12class Fee implements Payable 13{ 14 void pay() 15 { 16 System.out.println("paid"); 17 } 18}
Show the answer
A — "Illegal modifier for the interface field Payable.amount"
An interface holds no ordinary state. Any field in an interface is automatically public static final — a constant — so private is refused. Interfaces describe behaviour, not data.

B — "Cannot instantiate the type Payable"
The same refusal abstract classes gave in Module 3, for the same reason: pay() has no body, so the object would be unusable.

C — "Cannot reduce the visibility of the inherited method from Payable"
pay() is public in the interface. Omitting public on line 14 makes it package-private, which is narrower. Fix: public void pay().
CHUNK 7 OF 7 0:42 – 0:45

Checkpoint — which one, and why

Three designs. For each, choose interface or abstract class and justify in one line.

1. SavingsAccount and CurrentAccount both hold a balance and an account number, and both need their own calculateInterest().
2. A Drone, a Parrot and a Kite all need a fly() method.
3. Every class in a payroll system must be able to exportToCsv(), and most of them should share one standard implementation.

Show worked solution
1. Abstract class. They share real state — balance and account number — which an interface cannot hold. They are also genuinely two kinds of the same thing, so "is a kind of" fits. Put the shared fields and a concrete deposit() in the parent, leave calculateInterest() abstract.

2. Interface. A drone, a bird and a kite are not kinds of one another — there is no sensible shared parent. They share only a capability, and "is capable of" is exactly what an interface expresses. An abstract Flyer parent would also burn each class's single extends slot for nothing.

3. Interface with a default method. The capability is needed across unrelated classes, so an interface — but a shared standard implementation belongs in a default body, so no class has to write it and any class may still override it.

Practice

Three problems

Attempt each before opening the solution.
1 Write an interface Playable with play() and stop(), implemented by Guitar and Radio. Drive both through one array declared as the interface type.
Show solution
1interface Playable 2{ 3 void play(); 4 void stop(); 5} 6 7class Guitar implements Playable 8{ 9 public void play() { System.out.println("Strumming"); } 10 public void stop() { System.out.println("Muting strings"); } 11} 12 13class Radio implements Playable 14{ 15 public void play() { System.out.println("Tuning to 93.5 FM"); } 16 public void stop() { System.out.println("Switched off"); } 17}
1Playable g = new Guitar(); 2Playable r = new Radio(); 3 4g.play(); 5g.stop(); 6 7r.play(); 8r.stop();
Strumming Muting strings Tuning to 93.5 FM Switched off
A guitar and a radio have no sensible shared parent — which is the signal that this had to be an interface rather than an abstract class.
2 An interface has ten signers. You need to add a new method describe(). How do you add it without breaking any of the ten, and what is the trade-off?
Show solution
Add it as a default method with a working body:
1default String describe() 2{ 3 return "No description provided"; 4}
All ten keep compiling untouched, and each may override it later if it wants something better.

The trade-off: a default is a guess on behalf of classes you may never have seen. If the fallback is wrong for some of them, they will silently inherit wrong behaviour rather than being told to supply their own. Use a default when a sensible neutral answer exists; declare it abstract and accept the breakage when every class genuinely must decide for itself.
3 Can a class both extend an abstract class and implements an interface at the same time? Write the header line if so.
Show solution
Yes — and this is very common. extends comes first, then implements:
1class ReserveTrain extends Reservation implements Printable, Refundable 2{ 3 // must supply Reservation's abstract methods, 4 // plus every method of both interfaces 5}
One parent class for shared state and code; any number of interfaces for capabilities. The two mechanisms answer different questions, so they combine cleanly.

Project so far

Unit2Project
  • src
    • m2 school / ClassMonitor.java
    • m3 travel / Reservation.java · ReserveTrain · ReserveBus
    • m4 campus / College.java · InnerDemo · AnonDemo
    • safety
      • new FireSafety.java
      • new Accessible.java
      • new School.java
      • new Hospital.java
      • new LibraryDemo.java

Module 6 begins Packages — the folders themselves become the subject.

UP NEXT · MODULE 6
Packages — Concept & Manual Creation
Modules 6–15 arrive in this same file
press ↓ again, or click
Module 6 · Packages — Concept & Manual Creation
0%
35 min
next   back   chunk
MODULE 6 · PACKAGES: CONCEPT & MANUAL CREATION · 45 MIN
CHUNK 1 OF 7 0:00 – 0:05

A package is a folder

Modules 2 to 5 filled one folder with classes. A real project has dozens, and two of them eventually want the same name. That is what a package solves.

Covering the syllabus phrase: Classes and Interfaces — Package
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

That is the whole idea, and it is worth saying plainly before any tool gets involved. A package is a folder on your disk. Nothing more mysterious than that.

Java uses folders for the same reasons you do:

To group what belongs together. All the booking classes in one place, all the safety classes in another.
To allow the same name twice. A Library in one folder and a Library in another are two different classes, and Java can tell them apart.
To control what outsiders can see. Classes in the same folder get privileges that classes elsewhere do not — Module 7 covers this in full.

The one rule that binds them

THE RULE
The package line written inside a file must exactly match the folder path that file sits in. package college.exams; means the file lives in a folder called exams, inside a folder called college. Mismatch it and nothing runs.
ON DISK college exams Paper.java must match INSIDE THE FILE package college.exams; class Paper { } the dot is the folder separator
FOLDER PATH ON THE LEFT · PACKAGE LINE ON THE RIGHT · THEY SAY THE SAME THING

You have already been using packages — school, travel, campus, safety. Eclipse created the folders silently each time. This module removes the tool so you can see what it was doing.

CHUNK 2 OF 7 0:05 – 0:11

Building it by hand

Close Eclipse. For this module you need two things only: a plain text editor and a command window.

It is fair to ask why, when Eclipse does all of this in two clicks. Three reasons:

You see that a package really is a folder. Eclipse shows college.exams as one flat row and hides the nesting. Doing it by hand, you make the folders yourself.
You learn what breaks and why. When Eclipse reports a package error later, you will recognise it because you caused it here deliberately.
Exams ask for it. Questions about javac, -d, and running by fully qualified name expect the manual picture, not the IDE one.
1Make a folder on your D: drive called ManualDemo. This stands in for the project.
2Inside it, make a folder called college
3Inside college, make a folder called exams
4Open Notepad++ and save an empty file as Paper.java inside exams
Saving in Notepad++ needs care. In the Save dialog, set Save as type to All types (*.*) before typing the name. Leave it on "Text file" and you get Paper.java.txt, which the compiler will not accept.

What you should have now

D:\ManualDemo
collegepackage
examssub-package
Paper.javaempty

Two folders, one empty file. No tool made these — you did, with the same right-click you would use for any folder.

The package statement

Now the file declares where it lives. This line must be the very first line of code in the file — nothing but comments may come before it.

Java is strict about the order at the top of every file, and the order is always the same three things:

1package — where this file lives. At most one, and it comes first.
2import — what this file borrows from elsewhere. As many as needed.
3The class itself.

Put an import above the package line and it will not compile. The order is not a convention — it is part of the language.

D:\ManualDemo\college\exams\Paper.java
1package college.exams;
2
3public class Paper
4{
5 public void show()
6 {
7 System.out.println("Question paper ready");
8 }
9
10 public static void main(String[] args)
11 {
12 new Paper().show();
13 }
14}
Console
terminated
<terminated> college.office.PaperDemo [Java Application]
Question paper ready

Run from D:\ManualDemo with java college.office.PaperDemo once the driver in Chunk 5 exists.

Code on this page can't be copied — type it out. Typing is where it sticks.
package The keyword. It announces which folder this file belongs to, and it appears once per file at the top.
college.exams The folder path, with a dot where you would normally write a backslash. college\\exams on disk becomes college.exams in code.
the semicolon It is a statement like any other, so it ends in ;. Forgetting it is the most common first error here.
CHUNK 3 OF 7 0:11 – 0:18

Compiling it yourself

Open a command window in the ManualDemo folder — not in exams. Where you stand matters, and the next chunk shows why.

COMMANDjavac -d . college\exams\Paper.java

Four pieces, each doing one job:

javac — the Java compiler. It turns .java source into .class bytecode.
-d — "destination". It tells javac where to put the compiled output, and to build the package folders there itself.
. — the destination, meaning "right here, the folder I am standing in".
college\exams\Paper.java — which file to compile, given as a path from where you stand.
WHY -d
Without -d, the .class file lands beside the source, inside exams, and Java will not find it as part of a package. -d . is what makes the compiled output respect the package structure.
A silent command window is success. javac prints nothing when it works. If you see nothing at all, it compiled.

Running it — the full name matters

A class inside a package is no longer called Paper. Its real name now includes the package.

COMMANDjava college.exams.PaperDemo

Notice there is no .class on the end and no backslashes. You give java the class name, not a file path — and the full class name uses dots.

This trips people up because javac and java want different things from you, and they look similar on the line.

javac takes a file. It needs to find a .java file on disk, so you give it a path with backslashes and the extension: college\exams\Paper.java
java takes a class. It needs a class name, so you give it dots and no extension: college.exams.Paper
Both are read from where you stand. That is why the folder you run them from matters as much as what you type.

The reason for the second rule is worth knowing. Java starts at your current folder and treats each dot as "go one folder deeper". college.office.PaperDemo means: look for a folder college, then office inside it, then a file PaperDemo.class inside that.

Wrong
Right
What you type
java Paper
java college.exams.Paper
Why
There is no class simply called Paper any more
The package is part of the name now
Where you stand
inside exams
in ManualDemo, above the package folders
Stand above the package, always. Java starts at the folder you are in and follows the dots downward as folders. From ManualDemo it can find college, then exams. From inside exams there is nowhere left to go, and you get "Could not find or load main class".
CHUNK 4 OF 7 0:18 – 0:22

The finished structure

After compiling, the folder contains both what you wrote and what javac produced.

D:\ManualDemoyou stand here
college
exams
Paper.javayou typed this
Paper.classjavac made this

The .class file sits beside its source because you compiled with -d . from ManualDemo, and javac rebuilt the same college\exams path underneath. Source and output mirror each other exactly.

CHUNK 5 OF 7 0:22 – 0:29

Two packages, joined by import

One package alone proves little. The real question is how a class in one folder reaches a class in another.

Add a second package, college.office, holding a class that uses Paper.

D:\ManualDemo\college\office\PaperDemo.java
1package college.office;
2
3import college.exams.Paper;
4
5public class PaperDemo
6{
7 public static void main(String[] args)
8 {
9 Paper p = new Paper();
10 p.show();
11 }
12}
import Line 3 says "when I write Paper, I mean the one in college.exams". Without it, line 9 fails — this file's own folder has no Paper in it.
order matters package first, then import, then the class. Java will not accept them in any other order.
public was needed Paper and show() are both public. Had either been left plain, this file could not touch them from a different package — the subject of Module 7.

Compiling and running both

COMMANDjavac -d . college\exams\Paper.java college\office\PaperDemo.javajava college.office.PaperDemo
OUTPUTQuestion paper ready

Both files are listed in one javac command so the compiler sees them together. Then the program is run by its full name, from ManualDemo, exactly as before.

CHUNK 6 OF 7 0:29 – 0:33

What packages actually buy you

You could put every class loose in one folder. Java allows it. Here is what you lose by doing so.

Names stop colliding. Two classes called Library can coexist as college.Library and city.Library. Without packages the second one simply cannot exist.
Related code stays together. Every booking class in travel, every safety class in safety. Finding something becomes navigation rather than searching.
A boundary appears that Java enforces. Classes in one package can be hidden from every other package — the access control Module 7 builds on. Without packages there is no boundary to enforce.
Large projects stay possible. The Java library itself is thousands of classes across hundreds of packages. Flat, it would be unusable.
WHEN TO REACH FOR ONE
As soon as a project has more than a handful of classes, or any two that could share a name. Retrofitting packages later means touching every file.
The word for where Java looks. The classpath is the list of folders Java searches for classes. Running java from the folder above the package works because . — the current folder — is on the classpath by default, and college.exams.Paper is then found at .\college\exams\Paper.class.

The two mistakes everyone makes

1. The package line doesn't match the folder

The file sits in college\exams but its first line says something else.

1package college.exam;
2
3public class Paper
Could not find or load main class college.exams.PaperDemo
Compiles, then fails at run time

Why it's nasty: javac -d . happily creates a folder called exam to match what you wrote. Nothing complains until you try to run it. One missing letter, and the compiler quietly builds you the wrong structure.

2. The folder doesn't exist

You wrote the package line first and never created the matching folder.

 javac -d . college\exams\Paper.java
error: file not found: college\exams\Paper.java
Fails immediately, before compiling anything

Why it's kinder: this one fails loudly and straight away. The package statement does not create folders — it only declares where the file already is. You make the folders; the statement describes them.

Check the spelling in three places whenever something won't run: the folder name, the package line, and the name you typed after java. All three must agree exactly, including capitals.
CHUNK 7 OF 7 0:33 – 0:35

Recap — and what Module 7 will remove

Everything you just did by hand, Eclipse does for you in two clicks. Knowing the manual version is what lets you fix it when the tool gets it wrong.

1. What does -d . tell javac to do, in one sentence?
2. A file in shop\billing should start with which line?
3. From which folder do you run java shop.billing.Invoice?

Show answers
1. Put the compiled .class files in the current folder, rebuilding the package folder structure there.

2. package shop.billing; — dots where the backslashes are.

3. The folder containing shop, not shop or billing. Java follows the dots downward from where you stand.

Carry forward: a package is a folder, the package line describes it, and public is what let one package's class be used from another. Module 7 turns that last point into the full access-control picture.

Practice

Three problems

Attempt each before opening the solution.
1 You have D:\Shop\billing\Invoice.java. Write its first line, then the command that compiles it, standing in D:\Shop.
Show solution
First line of the file:
1package billing;
The folder billing sits directly inside Shop, and Shop is where you stand — so the package is just billing, with no Shop in front of it.

The command:
1javac -d . billing\Invoice.java
2 A classmate's program compiles but java Invoice reports "Could not find or load main class Invoice". The file is correct. What is wrong, and what should they type?
Show solution
They used the short name. Once a class is in a package, its real name includes that package — there is no class called plain Invoice any more.

They should type java billing.Invoice, standing in D:\Shop.

If it still fails, they are standing in the wrong folder. Running from inside billing cannot work, because Java looks for a folder called billing below where it starts.
3 Two classes, shop.billing.Invoice and shop.staff.Cashier. Cashier needs to create an Invoice. Write the top three lines of Cashier.java.
Show solution
1package shop.staff; 2 3import shop.billing.Invoice;
Own package first, then what it borrows from elsewhere. Being in shop together is not enough — billing and staff are different packages, so the import is required.

Invoice and any method Cashier calls on it must also be public, or the import will not save it.

Project so far

Two projects now
  • Unit2Project — in Eclipse
    • m2 school / ClassMonitor.java
    • m3 travel / Reservation.java · ReserveTrain · ReserveBus
    • m4 campus / College.java · InnerDemo · AnonDemo
    • m5 safety / FireSafety.java · LibraryDemo.java
  • ManualDemo — built by hand
    • new college / exams / Paper.java
    • new college / office / PaperDemo.java

Module 7 rebuilds this same structure inside Eclipse, then uses it to teach access control.

UP NEXT · MODULE 7
Packages — Eclipse Method & Access Control
Modules 7–15 arrive in this same file
press ↓ again, or click
Module 7 · Packages, Access Control & Encapsulation
0%
45 min
next   back   chunk
MODULE 7 · PACKAGES: ECLIPSE METHOD & ACCESS CONTROL · 35 MIN
CHUNK 1 OF 10 0:00 – 0:05

The same thing, in two clicks

Covering the syllabus phrase: Classes and Interfaces — Package (continued)
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Module 6 had you make folders, type the package line, and compile by hand. Eclipse does all three from one dialog. You are about to rebuild the identical structure — college.exams and college.office — the fast way.

1In Package Explorer, right-click the src folder of Unit2Project
2Choose New → Package
3Type the full name with dots: college.exams — not one folder at a time
4Press Finish, then repeat for college.office
New Java Package
Source folder:
Unit2Project/src
Name:
college.exams
Cancel
Finish
Type the dots, not the folders. Writing college.exams makes both levels at once. Making a package called college and then another called exams gives you two unrelated packages side by side, not one inside the other.

What Eclipse produced

Unit2Project
src
college.examsnew
college.officenew

Eclipse shows college.exams as one flat row. On disk it is still two nested folders — exactly what you built by hand. The display is a convenience; the structure is unchanged.

What just got done for you

Every manual step from Module 6 still happens. Eclipse simply performs each one without telling you.

The step
By hand (Module 6)
In Eclipse
Make the folders
Right-click → New Folder, twice
Typed once as college.exams
Write the package line
You type it, and must match it
Written into every new class automatically
Compile
javac -d . path\File.java
On every save, silently
Run
java college.office.PaperDemo
Green ▶ button
Keep them matching
Entirely your job
Eclipse rewrites the line if you move the file
WHY IT MATTERED
The last row is the real reason Module 6 came first. When Eclipse rewrites a package line and something stops working, you now know what it rewrote and what it must match. Without that, the tool is doing something invisible and unfixable.
CHUNK 2 OF 10 0:05 – 0:10

Who is allowed to see what

Now that classes live in different packages, a question arises that never came up before: can a class in college.office touch something in college.exams?

Java answers with four levels of access. You have already met two of them without being told their names.

private — only inside this same class. Nothing outside can reach it, not even a subclass. This is the lock you used on the Singleton constructor.
no word at all — called default or package-private. Visible to any class in the same package, and nothing beyond it. This is what your plain fields have been using.
protected — same package, plus subclasses anywhere, even in other packages. Inheritance is the only thing that opens the extra door.
public — visible everywhere, from any package, to anybody. This is why Paper and show() had to be public in Module 6.

The same four, as a grid

SAME CLASS SAME PACKAGE SUBCLASS other package ANYWHERE private (default) protected public each row opens one more door than the row above it
FOUR LEVELS · EACH ONE WIDER THAN THE LAST

Read it top to bottom and the pattern is simple: every level keeps everything the level above allowed, and opens one more column. There are no exceptions to memorise.

CHUNK 3 OF 10 0:10 – 0:16

Worked example — across two packages

One class with all four levels on display, and a second class in a different package trying to reach each of them.

src / college / exams / Paper.java
1package college.exams;
2
3public class Paper
4{
5 public String title = "OOP through Java";
6 String code = "UI24PC320CS";
7 protected int marks = 70;
8 private String answerKey = "locked";
9
10 public static void main(String[] args)
11 {
12 Paper p = new Paper();
13 // same class, so all four are reachable here
14 System.out.println(p.title + " | " + p.code);
15 System.out.println(p.marks + " | " + p.answerKey);
16 }
17}
Saving is what compiles it. Press Ctrl + S after typing. Eclipse builds the file on every save, so red marks appear immediately — before you ever press Run. Run with the green button or Ctrl + F11.
Code on this page can't be copied — type it out. Typing is where it sticks.

Line 6 has no access word at all. That is the default level — it is a real choice, not an omission.

src / college / office / Clerk.java  — a different package
1package college.office;
2
3import college.exams.Paper;
4
5public class Clerk
6{
7 public static void main(String[] args)
8 {
9 Paper p = new Paper();
10
11 System.out.println(p.title); // works
12 System.out.println(p.code); // error
13 System.out.println(p.marks); // error
14 System.out.println(p.answerKey); // error
15 }
16}
11 System.out.println(p.title);
12 System.out.println(p.code);
13 System.out.println(p.marks);
14 System.out.println(p.answerKey);
The field Paper.code is not visible
The field Paper.marks is not visible
The field Paper.answerKey is not visible
Clerk.java · three Java Problems

One line works and three fail. Each for its own reason:

title is public — open to every package, so Clerk reads it freely.
code is default — open only inside college.exams. Clerk is in college.office, which is a different package no matter how similar the name looks.
marks is protected — the extra door only opens for subclasses. Clerk does not extend Paper, so it gets nothing beyond default.
answerKey is private — sealed inside Paper itself. No package, no subclass, no exception.
OUTPUT — after deleting lines 12–14OOP through Java
CHUNK 4 OF 10 0:16 – 0:20

Second example — change one thing, change the outcome

Keep Paper exactly as it was. Change only one detail about the second class: make it a subclass.

src / college / office / PracticalPaper.java
1package college.office;
2
3import college.exams.Paper;
4
5public class PracticalPaper extends Paper
6{
7 public void report()
8 {
9 System.out.println(title); // public - works
10 System.out.println(marks); // protected - NOW works
11 }
12
13 public static void main(String[] args)
14 {
15 new PracticalPaper().report();
16 }
17}
OUTPUTOOP through Java70
THE LESSON
Nothing about Paper changed. marks was refused to Clerk and granted to PracticalPaper, purely because one extends Paper and the other does not. protected is the only modifier whose answer depends on the relationship between the two classes, not just on where they sit.

code is still unreachable even here — default access cares only about the package, and college.office is still the wrong one. Inheritance does not help with default.

CHUNK 5 OF 10 0:20 – 0:25

Encapsulation — what the four levels are for

Access specifiers are the mechanism. Encapsulation is the reason they exist.

ENCAPSULATION
Keeping a class's inner workings hidden, and exposing only a controlled way to use it. The outside world gets a door, never a key to the whole building.

It is always the same two moves together. One without the other is not encapsulation:

Hide the data. The field goes private, so no outside code can reach it at all.
Offer a controlled way in. A public method that can check, reject, or adjust before anything changes.

You have built it three times already

Unit 1 private String name with getName(). The field was sealed; the method was the door.
Module 2 The private constructor with getInstance(). Same shape applied to object creation instead of to a field — which is why only one object can exist.
Module 5 An interface names methods and hides every implementation detail. Encapsulation at the level of a whole type.

Why it is worth the extra method

A public field seems simpler. Here is what the private-plus-method version buys, in a case you can picture:

Account.java  — the door, not the key
1public class Account
2{
3 private double balance = 0;
4
5 public void deposit(double amount)
6 {
7 if (amount > 0)
8 {
9 balance = balance + amount;
10 }
11 }
12
13 public double getBalance()
14 {
15 return balance;
16 }
17
18 public static void main(String[] args)
19 {
20 Account a = new Account();
21 a.deposit(500);
22 a.deposit(-900); // refused
23 System.out.println("Balance : " + a.getBalance());
24 }
25}
AccountDemo.java  — proving the door works
1public class AccountDemo
2{
3 public static void main(String[] args)
4 {
5 Account a = new Account();
6
7 a.deposit(500);
8 a.deposit(-900); // refused, silently
9
10 System.out.println("Balance : " + a.getBalance());
11 }
12}
Console
terminated
<terminated> AccountDemo [Java Application]
Balance : 500.0

The negative deposit never reached balance. No error, no crash — it was simply refused, and the object stayed valid.

Line 7 is the whole argument. With balance public, any line anywhere could write a.balance = -500; and nothing would stop it. Sealed behind deposit(), a negative amount is simply refused — and it is refused for every caller, forever, without any of them having to remember the rule.

A getter and setter for every field is not encapsulation. If setBalance() accepts anything at all, the field is public with extra typing. The checking is the point, not the method.
For the exam: if a question asks about access specifiers, name encapsulation as their purpose in the first line. If a question asks about encapsulation, name private fields plus public methods as how it is done. The two questions want the same material pointed in opposite directions.
CHUNK 6 OF 100:25 – 0:30

final — the other way to restrict

Access specifiers control who may use something. final controls whether it may be changed. Different question, and the two are often asked together.

final field Its value may be set once and never again. final int marks = 70; — any later assignment is refused by the compiler.
final method A subclass may inherit it but may not override it. Use when the behaviour must be identical everywhere, whatever the subclass.
final class Nobody may extend it at all. String is the famous example — no subclass of String can exist anywhere in Java.
all three forms
1final class Rulebook // nobody may extend this
2{
3 final int maxMarks = 100; // set once, never changed
4
5 public final void grade() // no subclass may override
6 {
7 System.out.println("Graded out of " + maxMarks);
8 }
9}
10
11public class FinalDemo
12{
13 public static void main(String[] args)
14 {
15 new Rulebook().grade();
16 }
17}
FinalDemo.java  — what final allows and refuses
1final class Rulebook
2{
3 final int maxMarks = 100;
4
5 public final void grade()
6 {
7 System.out.println("Graded out of " + maxMarks);
8 }
9}
10
11public class FinalDemo
12{
13 public static void main(String[] args)
14 {
15 Rulebook r = new Rulebook();
16 r.grade();
17 }
18}
Console
terminated
<terminated> FinalDemo [Java Application]
Graded out of 100

Now try to break each rule. Every one is refused before the program runs:

1class Extended extends Rulebook { }
2r.maxMarks = 90;
The type Extended cannot subclass the final class Rulebook
The final field Rulebook.maxMarks cannot be assigned

On a final class, marking methods final as well is redundant — there can be no subclass to override them.

PYQ · 4 MARKS
"Under what circumstances would you declare a member or class as final or protected? Justify your answer."

Answer it as two halves, because they solve opposite problems:

Declare final when a value or behaviour must not vary — a constant such as a maximum mark, a method whose logic is a rule rather than a choice, or a class whose correctness depends on nobody altering it.
Declare protected when a subclass genuinely needs a member but the wider program must not. It opens one door, for inheritance only.
Say why it matters: both narrow what the rest of the program can do, which is what makes the class safe to change later without breaking code elsewhere.
PYQ · 4 MARKS
"Explain the benefit of declaring a class as protected and final, and the risk if these are not applied."
Benefit when applied
Risk when not applied
final class
Its behaviour is fixed and can be relied on everywhere
A subclass can override methods and change meaning — code trusting the original breaks silently
protected member
Subclasses get what they need; outsiders get nothing
Left public, any class can touch internals; left private, legitimate subclasses are blocked

Worth stating in the answer: a class cannot itself be protected at the top level — only its members can. Say so and you show you know the boundary, which the question is quietly testing.

CHUNK 7 OF 100:30 – 0:34
ASKED IN CLASS — can a member be protected and final at once?

Yes. They answer two different questions, so they never collide.

protected answers "who may see it?" — same package, plus subclasses anywhere.
final answers "may it change?" — no, it is set once.
Together: "subclasses may read this, and nobody at all may change it."
Paper.java  — both words on one field
1package college.exams;
2
3public class Paper
4{
5 // BOTH words on one member - perfectly legal
6 protected final int maxMarks = 100;
7
8 // the class itself may only be public or default
9 // protected class Paper <- will not compile
10
11 public static void main(String[] args)
12 {
13 System.out.println(new Paper().maxMarks);
14 }
15}
Console
terminated
<terminated> college.exams.Paper [Java Application]
100

The follow-up: what if I leave it default instead?

Drop the word protected and the field becomes default access. Exactly one row changes:

Reader
protected final
final alone (default)
Same class
reads it
reads it
Another class, same package
reads it
reads it
Subclass in another package
reads it
refused
Anybody changing it
refused
refused
In our code
Paper.marks reached by PracticalPaper in another package
Default refuses it — different package, subclass or not

So the choice is narrow. If subclasses live in other packages and need the value, write protected final. If everything that needs it sits in this package, plain final is enough — and the smaller door is the better habit. final behaves identically either way; only visibility moves.

The part people get wrong: a top-level class can never be protected, with or without final — only public or default.

Immutable classes

An immutable object is one that can never change after it is built.

The word is the intimidating part. The idea is not.

YOU ALREADY USE ONE
Every String in Java is immutable. s.toUpperCase() does not change s — it hands you a new string and leaves the old one exactly as it was. That is all immutability means.
String s = "asha"; s.toUpperCase(); System.out.println(s);
Prints asha, not ASHA. The uppercase version was made and thrown away, because nothing can alter the original string. Students meet this bug in Unit 1 without being told the word for it.

So the question "how do I make a class immutable?" really means: how do I stop anyone changing my object after it is built? There are only three ways in, and the recipe closes all three.

Reach in and set a field directly — closed by making every field private.
Call a setter — closed by not writing any.
Subclass it and add a setter — closed by marking the class final.
THE RECIPE
1. Make every field private and final.
2. Set them all in the constructor.
3. Provide getters but no setters at all.
4. Mark the class final so no subclass can add mutable behaviour.
StudentId.java  — the recipe applied
1final class StudentId
2{
3 private final String roll;
4 private final int year;
5
6 StudentId(String r, int y)
7 {
8 roll = r;
9 year = y;
10 }
11
12 public String getRoll()
13 {
14 return roll;
15 }
16
17 public int getYear()
18 {
19 return year;
20 }
21
22 // no setters anywhere - that is the point
23
24 public static void main(String[] args)
25 {
26 StudentId id = new StudentId("1602-24-733-001", 2024);
27 System.out.println(id.getRoll() + " / " + id.getYear());
28 }
29}
StudentIdDemo.java  — built once, never changed
1public class StudentIdDemo
2{
3 public static void main(String[] args)
4 {
5 StudentId id = new StudentId("1602-24-733-001", 2024);
6
7 System.out.println("Roll : " + id.getRoll());
8 System.out.println("Year : " + id.getYear());
9 }
10}
Console
terminated
<terminated> StudentIdDemo [Java Application]
Roll : 1602-24-733-001Year : 2024

Every route to changing it is closed before the program runs:

1id.roll = "9999";
2id.setRoll("9999");
3class FakeId extends StudentId { }
The field StudentId.roll is not visible
The method setRoll(String) is undefined for the type StudentId
The type FakeId cannot subclass the final class StudentId
private · no setter · final class — three locks, three refusals
PYQ · 2 MARKS
"What is required to declare a class as immutable?"

Model answer

1
All fields private and final, assigned only in the constructor.
2
No setter methods, and no method that alters a field.
3
The class itself final, so no subclass can reintroduce change.
4
Name String as the example. It is immutable, which is why s.concat("x") returns a new string rather than altering s.
Why anyone wants this: an immutable object is safe to share anywhere without copying, and can never be left in a half-changed state. Module 12's thread work returns to exactly this point.
CHUNK 8 OF 100:34 – 0:37

The four pillars, all in hand

You have now met all four principles of object-oriented programming. Three came in Unit 1; the fourth was the section above.

PYQ · 4 MARKS
"Explain the key principles of object-oriented programming."
Abstraction Showing what a thing does and hiding how. An abstract class or an interface names reserve() without saying how any particular booking works. Modules 3 and 5.
Encapsulation Keeping data private and exposing a controlled way in. balance is private; deposit() checks before changing it. This module.
Inheritance A class taking on another's fields and methods with extends. ReserveTrain extends Reservation and gets printReceipt() free. Unit 1, used throughout Unit 2.
Polymorphism One name, many behaviours. A Reservation variable holding a train booking runs the train's reserve(). Unit 1, seen again in Modules 3 and 5.

All four in a single runnable program

Worth writing out in the answer if time allows — one short program demonstrating every pillar at once.

PillarsDemo.java  — all four, in one run
1abstract class Booking // ABSTRACTION
2{
3 private double paid; // ENCAPSULATION
4
5 public void pay(double amt)
6 {
7 if (amt > 0) { paid = amt; }
8 }
9
10 public double getPaid()
11 {
12 return paid;
13 }
14
15 public abstract void confirm();
16}
17
18class TrainBooking extends Booking // INHERITANCE
19{
20 public void confirm() // POLYMORPHISM
21 {
22 System.out.println("Train seat confirmed");
23 }
24}
25
26public class PillarsDemo
27{
28 public static void main(String[] args)
29 {
30 Booking b = new TrainBooking();
31 b.pay(450);
32 b.confirm();
33 System.out.println("Paid : " + b.getPaid());
34 }
35}
Console
terminated
<terminated> PillarsDemo [Java Application]
Train seat confirmedPaid : 450.0

Four comments mark the four pillars. Booking is abstract and hides how confirming works; paid is private with a checked setter; TrainBooking extends; and a Booking variable runs the train's confirm().

Full marks needs one line plus one example each. Four pillars, four sentences, four examples — and every example above is something you have already built, so none of it has to be invented in the hall.
CHUNK 9 OF 10 0:37 – 0:42

Why bother restricting access at all

Every field could be public and the program would still run. Access control is not about making things work — it is about what happens next.

Invalid states become impossible. A private balance can only change through a method that checks the amount first. A public one can be set to minus a million by any line anywhere.
You can change your mind later. Nothing outside depends on a private field, so it can be renamed or replaced freely. A public field is a promise you cannot withdraw without breaking other code.
The class says what it is for. The public members are the intended way to use it; everything else is machinery. Marking it so saves the next reader from guessing.
Mistakes surface at compile time. "The field is not visible" appears while you type — not as wrong behaviour found in an exam hall.
THE DEFAULT HABIT
Start every field at private and every class at default. Widen only when something genuinely needs the access, and only as far as it needs. Narrowing later breaks code; widening later never does.

Exam landing

PYQ · 4 MARKS
"Discuss the access specifiers in Java in detail."

The word the examiner wants: encapsulation

Access specifiers exist to serve one idea, and naming it correctly is worth a mark on its own.

DEFINITION
Encapsulation means keeping a class's data hidden inside it, and letting the outside world touch that data only through methods the class chooses to offer. The data and the methods that guard it are wrapped together — that wrapping is what the word describes.

Two halves, and both are needed:

Hide the data — mark fields private so no outside line can reach them.
Offer a controlled way inpublic methods that can check, adjust or refuse before anything changes.

A private balance with a public deposit() that rejects negative amounts is encapsulation. A public balance is not, no matter how many methods sit beside it — because the guard can simply be walked around.

You have been doing this since Module 2 without the name. ClassMonitor hid name and offered getName(); the Singleton hid its constructor and offered getInstance(). Encapsulation is the principle; access specifiers are the tool that enforces it.

How to structure the answer

1
Open with the purpose — access specifiers decide which other classes may use a field, method or class. They enforce encapsulation — keeping a class's inner workings hidden and exposing only a controlled way in — rather than merely suggesting it.
2
Name all four, widest to narrowest or the reverse, but be consistent: private, default, protected, public.
3
Draw the visibility table. It earns marks on its own and takes under a minute.
4
Add one short code example showing a refusal — the error message proves you have actually met the rule.

The table to draw

Specifier
Visible to
Typical use
private
The same class only
Fields you never want touched directly; the Singleton constructor
default (no word)
Any class in the same package
Helper classes meant only for their own package
protected
Same package, plus subclasses in any package
Members a subclass must reach, but outsiders must not
public
Every class, every package
The intended interface of your class

The short program to write in the answer

One class showing all four levels, run from inside itself where every one is reachable — then the same fields read from another package, where three are refused.

bank / Demo.java
1package bank;
2
3public class Demo
4{
5 public String owner = "Asha";
6 String branch = "Vasavi"; // default
7 protected int code = 17;
8 private String pin = "4417";
9
10 public static void main(String[] args)
11 {
12 Demo d = new Demo();
13 // all four reachable here - same class
14 System.out.println(d.owner + " | " + d.branch);
15 System.out.println(d.code + " | " + d.pin);
16 }
17}
Console
terminated
<terminated> bank.Demo [Java Application]
Asha | Vasavi17 | 4417

Then say what changes from outside. Move the reader to another package and only owner still prints — branch, code and pin each fail with "is not visible", for the three different reasons in the table above.

Points that earn the extra marks

Default is a real level, not an absence. Writing no word chooses package-private deliberately. Many answers miss this and lose a mark.
A top-level class may only be public or default. It cannot be private or protected — those apply to members inside a class.
A public class must sit in a file of the same name. That is why Paper lives in Paper.java.
protected is wider than default, not narrower. It grants everything default grants, then adds subclasses elsewhere.

The two mistakes

1. A class dragged into a package, without its package line

You copy an old .java file into college.exams using your file manager rather than Eclipse. The file still says nothing about a package, or says the old one.

1public class Paper
2{
The declared package "" does not match the expected package "college.exams"
Paper.java · line 1

The fix: add package college.exams; as line 1. Better still, move files with Eclipse's own Refactor → Move, which rewrites the line for you. This is the same mismatch from Module 6, except Eclipse catches it the instant it happens instead of letting it fail at run time.

2. Believing default and protected are the same

They overlap heavily, which is exactly why they get confused. One column separates them.

default
protected
Same package
Yes
Yes
Subclass, same package
Yes
Yes
Subclass, different package
No
Yes
Unrelated class, different package
No
No

One row differs. That row is the entire distinction, and it is exactly what chunk 5 demonstrated: PracticalPaper reached marks from another package because it inherited, and could not reach code for the same reason it never could.

CHUNK 10 OF 10 0:42 – 0:45

Checkpoint — choose the modifier

A BankAccount class in package bank.core. Pick the right level for each, and say why in one line.

1. balance — must never be changed except through the class's own methods.
2. deposit() — the whole program, including other packages, must be able to call it.
3. calculateInterest() — subclasses like SavingsAccount in bank.products need it, but nobody else should.
4. AuditLog — a helper class used only by other classes inside bank.core.

Show worked solution
1. private double balance; — sealed inside the class, so every change must go through a method that can check it. This is encapsulation in one word.

2. public void deposit(...) — it is part of the intended interface, so it must be reachable from any package.

3. protected double calculateInterest() — subclasses sit in a different package, so default would refuse them. protected is the only level that opens that one door without opening it to everybody.

4. class AuditLog — no word at all. Default keeps it visible inside bank.core and invisible outside. Note it cannot be private: a top-level class only has public or default available.

Practice

Three problems

Attempt each before opening the solution.
1 A class in shop.billing has a field with no access word. Which of these can read it? (a) another class in shop.billing (b) a subclass in shop.staff (c) any class in shop
Show solution
Only (a).

Default access means the same package and nothing else. shop.staff is a different package, and inheriting does not help — that is protected's power, not default's. And shop is a different package again: shop and shop.billing are separate, not parent and child in any access sense.
2 Why can a top-level class never be declared private? Answer in two lines.
Show solution
private means "visible only inside the enclosing class". A top-level class has no enclosing class, so private would leave it visible to nothing at all — an unusable class.

Java therefore allows only public or default at the top level. A nested class does have an enclosing class, so there private is legal — which ties back to Module 4.
3 Predict the errors. Paper is unchanged from chunk 4.
1package college.exams; 2 3public class Examiner 4{ 5 void check() 6 { 7 Paper p = new Paper(); 8 System.out.println(p.title); 9 System.out.println(p.code); 10 System.out.println(p.marks); 11 System.out.println(p.answerKey); 12 } 13}
Show solution
Only line 11 fails"The field Paper.answerKey is not visible".

The difference from chunk 4 is line 1: Examiner is in college.exams, the same package as Paper.

OOP through Java UI24PC320CS 70
title is public. code is default — same package, so allowed. marks is protected, which includes same-package access. Only answerKey is private, and private never leaves its own class.

Same four fields, same four lines, opposite outcome — decided entirely by which package the reader sits in.

Project so far

Unit2Project
  • m2 school / ClassMonitor.java
  • m3 travel / Reservation.java · ReserveTrain · ReserveBus
  • m4 campus / College.java · InnerDemo · AnonDemo
  • m5 safety / FireSafety.java · LibraryDemo.java
  • college — rebuilt in Eclipse
    • new college.exams / Paper.java
    • new college.office / Clerk.java
    • new college.office / PracticalPaper.java

Packages are finished. Module 8 opens Exception Handling — the largest topic in the unit.

UP NEXT · MODULE 8
Exception Handling — Fundamentals
Modules 8–15 arrive in this same file
press ↓ again, or click
Module 8 · Exception Handling — Fundamentals
0%
40 min
next   back   chunk
MODULE 8 · EXCEPTION HANDLING: FUNDAMENTALS · 40 MIN
CHUNK 1 OF 7 0:00 – 0:07

When a program stops rather than continues

Covering the syllabus phrases: Exception Handling — Introduction and syntax of exception handling code
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Everything you have written so far has worked. That is because nothing has been asked to do the impossible yet.

Ask Java to divide by zero and it cannot produce an answer. It has two options: pretend, or stop. It stops — and it tells you exactly why.

Creating the file

1Right-click src in Package Explorer → New → Package, name it marks, press Finish. Skip this once the package exists.
2Right-click the marks package → New → Class.
3Type Average in Name, and tick public static void main(String[] args).
4Press Finish. Type the code in, then Ctrl + S to save — Eclipse compiles the moment you save.
5Run it with the green button, or Ctrl + F11.
New Java Class
Source folder:
Unit2Project/src
Package:
marks
Name:
Average
Method stubs:
public static void main(String[] args)
Cancel
Finish

Ticking the main box matters. Every program in this module is run directly, so each class needs its own main. Forget the tick and you can add it by hand — but the wizard is quicker.

src / marks / Average.java  — no protection at all
1package marks;
2
3public class Average
4{
5 public static void main(String[] args)
6 {
7 int total = 240;
8 int subjects = 0; // nobody entered the subjects yet
9
10 System.out.println("Working out the average...");
11 System.out.println(total / subjects);
12 System.out.println("Done.");
13 }
14}
Console
terminated
<terminated> marks.Average [Java Application]
Working out the average...Exception in thread "main" java.lang.ArithmeticException: / by zero at marks.Average.main(Average.java:11)
Code on this page can't be copied — type it out. Typing is where it sticks.

Three things in that output are worth reading carefully:

Line 10 printed. Line 12 did not. The program did not fail from the start — it ran until it hit the impossible line, then stopped dead. Everything after was abandoned.
It names the problem: ArithmeticException: / by zero. Java tells you what went wrong, in words.
It names the line: Average.java:11. Click that in Eclipse and the cursor lands on the exact statement.

Error or exception — are they the same thing?

The words get used loosely in conversation, so here is what each means precisely in Java.

compile errorNot an exception at all. Your code is not valid Java, so nothing runs. Eclipse marks it red as you type. try/catch is useless here — Module 3's "Cannot instantiate" was one of these.
exceptionA run-time problem you can deal with. The code was valid; it met a value it could not handle. This is the whole subject of Modules 8 to 10.
Error (the Java class)A run-time problem you cannot sensibly deal with — the JVM running out of memory, for instance. Technically catchable; in practice, leave it alone. Module 9 shows where it sits.
THE SHORT VERSION
A compile error means the program cannot run. An exception means it ran and hit trouble it can survive. An Error means it ran and hit trouble it cannot. Only the middle one is yours to catch.
AN EXCEPTION IS
An object Java creates the moment something goes wrong at run time. It carries the kind of problem and where it happened. If nobody catches it, the program stops and the message is printed for you.

Note the word "run time". This is not a compiler error — the program compiled perfectly. Module 3's "Cannot instantiate" was caught before running; this one only appears once it is running with real values.

CHUNK 2 OF 7 0:07 – 0:14

try and catch — fixing that exact crash

You cannot stop division by zero being impossible. What you can do is tell Java: if this goes wrong, here is what to do instead of stopping.

THE SHAPE
try holds the risky code. catch holds what to do if it fails. Only one of the two ever runs to completion — either the try finishes, or control jumps to the catch.
try { risky code here }
"Attempt this." Java runs it normally. The moment any line inside throws, the rest of the block is skipped instantly.
catch (ArithmeticException e) { what to do instead }
"If it failed this way, do this." The type in brackets says which problem this block handles. e is the exception object itself, carrying the message.
src / marks / Average.java  — the same program, protected
1package marks;
2
3public class Average
4{
5 public static void main(String[] args)
6 {
7 int total = 240;
8 int subjects = 0;
9
10 System.out.println("Working out the average...");
11
12 try
13 {
14 System.out.println(total / subjects);
15 }
16 catch (ArithmeticException e)
17 {
18 System.out.println("No subjects entered yet.");
19 }
20
21 System.out.println("Done.");
22 }
23}
Console
terminated
<terminated> marks.Average [Java Application]
Working out the average...No subjects entered yet.Done.

Compare that with the crash on the last page. Same impossible division, same line. But now Done. printed — the program survived and carried on. That is the entire purpose of exception handling.

What the message costs you

Printing your own sentence is friendlier, but it throws away Java's detail. When you want both, use the exception object:

1catch (ArithmeticException e) 2{ 3 System.out.println("No subjects entered yet."); 4 System.out.println("Java said: " + e.getMessage()); 5}
No subjects entered yet. Java said: / by zero
ASKED IN CLASS — why not just use if and print a message?

A fair question, and for the small example above the if is genuinely fine. Nobody should throw an exception where a simple check will do.

1static void average(int total, int subjects) 2{ 3 if (subjects == 0) 4 { 5 System.out.println("cannot divide by zero"); 6 return; 7 } 8 System.out.println(total / subjects); 9}

That works. So the honest answer is not "exceptions are better" — it is that an if stops being enough as soon as one of these three things is true.

1. The method has to return a value. Above, the method returns nothing, so return; works. If it returned an int, what would you return on failure? 0 is a real average. -1 is a lie the caller must remember to check for. There is no number that means "this did not work".
2. The place that detects the problem cannot fix it. A method that reads a mark knows the value is wrong, but has no idea whether to re-prompt, log it, or refuse the student. Throwing hands the decision to whoever called it — who does know.
3. Nobody can forget to handle it. A printed message can be ignored; the program carries on with bad data. A checked exception is refused by the compiler until the caller deals with it. That is the one thing an if can never do.

The honest comparison

if and print
throw an exception
Simple local check
Better — shorter and clearer
overkill
Method must return a value
no honest value to return
Better
Caller must decide what to do
cannot pass the decision on
Better
Must not be ignorable
a message is easily missed
Better — compiler enforces it
Carries the detail
only what you print
type and message travel together
In our code
Average.java — one catch around the division
ResultCard.java — three catches plus finally

The rule of thumb: use if when this method can handle the problem itself. Throw when it cannot, and somebody further up must be told.

And note what if cannot prevent at all. You can check subjects == 0 because you wrote that line. You cannot write an if in front of every array access in a program, and you certainly cannot check for a problem inside code somebody else wrote. Exceptions catch the failures you did not predict — which is most of them.

An empty catch block is the worst thing you can write. catch (Exception e) { } compiles, hides the problem completely, and leaves nobody — including you — any way of knowing something went wrong.
CHUNK 3 OF 7 0:14 – 0:21
Reading a stack trace. Those indented at ... lines are the call stack — which method called which, innermost first. When no catch matches, the exception propagates up that stack, method by method, until something catches it or the program stops. The top line says what went wrong; the lines below say how you got there.

Multiple catch blocks

Covering the syllabus phrase: multiple catch statements

One try can go wrong in more than one way, and each way may deserve a different response. You are allowed as many catch blocks after a single try as there are things that can fail.

HOW JAVA CHOOSES
Java checks the catch blocks top to bottom and runs the first one whose type matches. Exactly one runs — never two, never none-then-crash if a match exists. The rest are skipped entirely.
src / marks / TwoWays.java
1public class TwoWays
2{
3 public static void main(String[] args)
4 {
5 int[] marks = { 80, 75, 0 };
6
7 try
8 {
9 System.out.println(marks[5]); // only 3 slots exist
10 System.out.println(100 / marks[2]); // divide by zero
11 }
12 catch (ArrayIndexOutOfBoundsException e)
13 {
14 System.out.println("That subject number does not exist.");
15 }
16 catch (ArithmeticException e)
17 {
18 System.out.println("Cannot divide by a zero mark.");
19 }
20 }
21}
Console
terminated
<terminated> TwoWays [Java Application]
That subject number does not exist.
Why did the division message not print too?

Because line 10 never ran. Line 9 threw, so the rest of the try was abandoned immediately — the division never happened at all.

This catches people out constantly. A try block does not "run everything and collect the failures". It stops at the first one. To see the second message, you would have to fix line 9 first.

Where the exception actually goes

line 9 : marks[5] inside the try block ! throws ArrayIndexOutOfBounds an object, carrying the detail offered to catch (ArrayIndexOutOfBoundsException e) TYPE MATCHES — this one runs catch (ArithmeticException e) skipped — never even tested
FIRST MATCHING CATCH WINS · THE REST ARE SKIPPED
Order matters, and the compiler enforces it. Put catch (Exception e) first and every later catch becomes unreachable — Eclipse reports "Unreachable catch block". Always list the specific types first and the general one last.
CHUNK 4 OF 7 0:21 – 0:27

finally — the block that always runs

Covering the syllabus phrase: using finally statement

Some work must happen whether things went well or badly. Closing a file, releasing a seat, printing a footer. finally is where that goes.

THE GUARANTEE
A finally block runs every time — after a successful try, after a catch has handled a failure, even if the method returns from inside the try. If you must be sure something happens, put it here.

Both paths, side by side

NOTHING GOES WRONG try — runs to the end catch — skipped finally — RUNS SOMETHING FAILS try — stops part-way catch — handles it finally — RUNS two different routes, one shared ending
WHICHEVER WAY CONTROL TRAVELS, IT PASSES THROUGH FINALLY
src / marks / FinallyDemo.java  — run twice, one line changed
1public class FinallyDemo
2{
3 public static void main(String[] args)
4 {
5 int subjects = 3; // change to 0 for the second run
6
7 try
8 {
9 System.out.println("Average : " + (240 / subjects));
10 }
11 catch (ArithmeticException e)
12 {
13 System.out.println("Could not work it out.");
14 }
15 finally
16 {
17 System.out.println("-- report closed --");
18 }
19 }
20}
Console
terminated
<terminated> FinallyDemo [Java Application] — run 1, subjects = 3
Average : 80-- report closed --
Console
terminated
<terminated> FinallyDemo [Java Application] — run 2, subjects = 0
Could not work it out.-- report closed --

The first line differs between the two runs. The highlighted line does not. That is finally doing its one job.

CHUNK 5 OF 7 0:27 – 0:32

The three you will meet most

Hundreds of exception types exist. Three account for most of what a student actually hits, and all three have appeared already in this module.

ArithmeticException Integer division or remainder by zero. Only integers — 10.0 / 0 gives Infinity and throws nothing at all.
1int x = 10 / 0; // throws
ArrayIndexOutOfBoundsException An index that does not exist. Remember an array of 3 has indexes 0, 1, 2 — never 3.
1int[] a = { 1, 2, 3 }; 2System.out.println(a[3]); // throws
NullPointerException Using a reference that points at nothing. The variable exists; the object it should point at does not.
1String s = null; 2System.out.println(s.length()); // throws
Read the name and you have half the fix. Java's exception names are descriptions, not codes. ArrayIndexOutOfBounds literally says an array index went out of bounds — the message then tells you which one.
RECALL — from earlier modules
Two of these fail at compile time and two at run time. Which is which?
1Reservation r = new Reservation(); // Module 3 2int x = 10 / 0; // this module 3p.answerKey = "guess"; // Module 7, private field 4String s = null; s.length(); // this module
Show the answer
Compile time: lines 1 and 3. Both are refused before the program ever runs — "Cannot instantiate the type Reservation" and "The field Paper.answerKey is not visible". Eclipse marks them red as you type.

Run time: lines 2 and 4. Both compile perfectly. They only fail once running, with real values — and only these two are exceptions.

The distinction that matters: you cannot try/catch a compile error. Exception handling protects you from run-time problems only. If Eclipse is showing red before you press Run, no amount of catch will help.
CHUNK 6 OF 7 0:32 – 0:37

Worked example — everything together

One try, two catch blocks, one finally. This is the shape the exam asks for, and the shape Module 10's larger questions are built from.

src / marks / ResultCard.java  — complete and runnable
1package marks;
2
3public class ResultCard
4{
5 public static void main(String[] args)
6 {
7 int[] marks = { 72, 65, 80 };
8 int subjects = 0;
9
10 System.out.println("=== Result Card ===");
11
12 try
13 {
14 int total = marks[0] + marks[1] + marks[2];
15 System.out.println("Total : " + total);
16 System.out.println("Average : " + (total / subjects));
17 }
18 catch (ArrayIndexOutOfBoundsException e)
19 {
20 System.out.println("A subject is missing from the list.");
21 }
22 catch (ArithmeticException e)
23 {
24 System.out.println("Average unavailable : " + e.getMessage());
25 }
26 finally
27 {
28 System.out.println("=== End of card ===");
29 }
30 }
31}
Console
terminated
<terminated> marks.ResultCard [Java Application]
=== Result Card ===Total : 217Average unavailable : / by zero=== End of card ===

Trace it once and the whole module is in that output:

Line 15 printed — the try ran normally up to that point.
Line 16 threw, so the try stopped there.
The first catch was skipped — wrong type. The second matched and ran.
Finally ran anyway, closing the card exactly as it would have on a clean run.
CHUNK 7 OF 7 0:37 – 0:40

Checkpoint — predict the output

No new ideas. Just trace the order carefully.

1System.out.println("A"); 2try 3{ 4 System.out.println("B"); 5 int x = 5 / 0; 6 System.out.println("C"); 7} 8catch (ArithmeticException e) 9{ 10 System.out.println("D"); 11} 12finally 13{ 14 System.out.println("E"); 15} 16System.out.println("F");

1. Which letters print, and in what order?
2. Which letter never prints, and why?
3. If line 5 were 5 / 1 instead, what would change?

Show worked solution
1. A B D E F

2. C never prints. Line 5 threw, so the rest of the try was abandoned instantly — exactly the point from Chunk 3. Notice F still prints: the program survived, so execution continued past the whole try/catch/finally.

3. With 5 / 1 nothing throws, so you get A B C E F. C appears and D disappears — the catch is skipped because there was nothing to catch. E prints either way, which is the whole point of finally.

If you got all three: you have the fundamentals. Module 9 adds the exception types, and where exceptions come from when you throw them yourself.

Practice

Three problems

Attempt each before opening the solution.
1 Write a program that reads a student's name from an array of length 2, deliberately asks for index 4, and handles the failure without crashing. Print a closing line that runs either way.
Show solution
1public class NameLookup 2{ 3 public static void main(String[] args) 4 { 5 String[] names = { "Asha", "Ravi" }; 6 7 try 8 { 9 System.out.println(names[4]); 10 } 11 catch (ArrayIndexOutOfBoundsException e) 12 { 13 System.out.println("No student at that number."); 14 } 15 finally 16 { 17 System.out.println("Lookup finished."); 18 } 19 } 20}
No student at that number. Lookup finished.
2 This compiles with a warning and one catch can never run. Which one, and why?
1try { int x = 1 / 0; } 2catch (Exception e) { System.out.println("general"); } 3catch (ArithmeticException e) { System.out.println("maths"); }
Show solution
Line 3 can never run, and it is an error rather than a warning: "Unreachable catch block for ArithmeticException. It is already handled by the catch block for Exception".

Exception is the general type that every exception falls under, so putting it first catches everything — nothing is ever left for the specific block below.

The fix: swap them. Specific types first, Exception last if you want it at all. Java checks top to bottom and takes the first match, so the order you write them is the priority order.
3 A classmate says: "I put everything in one big try at the top of main and one catch (Exception e) at the bottom. Now nothing ever crashes." What is wrong with that?
Show solution
It stops the crash without solving anything. Three problems:

You lose the position. One catch around a hundred lines tells you something failed, not where. The stack trace that would have named the line is gone.

You lose the distinction. A missing subject and a division by zero deserve different messages. One catch can only give one.

The rest of the try is abandoned. If the failure happened on line 3 of 100, the other 97 lines never ran — and the program carries on as though they had, which is worse than stopping.

Better: wrap the smallest piece of code that can actually fail, catch the specific type, and let anything genuinely unexpected reach you as a real crash with a real stack trace.

Project so far

Unit2Project
  • m2 school / ClassMonitor.java
  • m3 travel / Reservation.java · ReserveTrain · ReserveBus
  • m4 campus / College.java · InnerDemo · AnonDemo
  • m5 safety / FireSafety.java · LibraryDemo.java
  • m7 college.exams / Paper.java · college.office / Clerk.java
  • marks — new this module
    • new Average.java
    • new TwoWays.java
    • new FinallyDemo.java
    • new ResultCard.java

Module 9 keeps the marks package and adds exception types, throw versus throws, and your own exception classes.

UP NEXT · MODULE 9
Exception Types, throw vs throws, Custom Exceptions
Modules 9–15 arrive in this same file
press ↓ again, or click
Module 9 · Exception Types, throw vs throws, Custom Exceptions
0%
40 min
next   back   chunk
MODULE 9 · EXCEPTION TYPES, THROW VS THROWS, CUSTOM EXCEPTIONS · 40 MIN
CHUNK 1 OF 7 0:00 – 0:07

Two families of exception

Covering the syllabus phrase: Exception Handling — types of exceptions
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Every exception in Module 8 behaved the same way: the program compiled fine, then failed while running. Those are only half the story.

Java splits exceptions into two families, and the difference is not about severity. It is about whether the compiler forces you to deal with it.

Unchecked — the compiler says nothing. You may handle it or ignore it; if you ignore it and it happens, the program crashes. Everything in Module 8 was this kind.
Checked — the compiler refuses to build your program until you either catch it or declare it. You cannot ignore one by accident.

Where they sit

Throwable Error the JVM's own problems — not yours to catch Exception CHECKED IOException compiler insists UNCHECKED RuntimeException compiler stays quiet every exception you met in Module 8 lives in the purple box
ONE FAMILY TREE · THE SPLIT THAT MATTERS IS CHECKED VERSUS UNCHECKED
THE TEST
Anything under RuntimeException is unchecked. Everything else under Exception is checked. That single line of inheritance decides whether the compiler will nag you.

Error covers things like running out of memory. They are technically catchable, but there is nothing sensible you could do about them, so leave them alone.

CHUNK 2 OF 7 0:07 – 0:13

Throwable — what sits above everything

Both families in the diagram trace back to one class: Throwable. It is the only type Java allows after the word throw, and the only type a catch block can name.

Throwable is the root. Nothing can be thrown unless it descends from it. It supplies getMessage() and printStackTrace() — which is why every exception you have met has them.
Exception is the branch for problems a program can reasonably recover from. Everything in this unit lives here.
Error is the other branch — failures of the machine itself, like StackOverflowError and OutOfMemoryError. Technically catchable; in practice never caught, because nothing sensible can be done about them.
src / marks / RootOfAll.java  — proving Throwable sits above both
1package marks;
2
3public class RootOfAll
4{
5 public static void main(String[] args)
6 {
7 try
8 {
9 int x = 10 / 0;
10 }
11 catch (Throwable t) // catches absolutely anything
12 {
13 System.out.println("Caught : " + t);
14 System.out.println("Its parent : "
15 + t.getClass().getSuperclass());
16 }
17 }
18}
Console
terminated
<terminated> marks.RootOfAll [Java Application]
Caught : java.lang.ArithmeticException: / by zeroIts parent : class java.lang.RuntimeException
WHY THIS MATTERS IN AN ANSWER
When a question says "explain the exception hierarchy", it wants Throwable at the top, splitting into Exception and Error, with Exception splitting again into checked and unchecked. Starting at Exception misses the top of the tree.
Do not write catch (Throwable t) in real code. It swallows Error too, so a program out of memory carries on pretending it is fine. It is shown above only to prove the hierarchy. catch (Exception e) is the widest net worth casting.

Exam landing

PYQ · 2 MARKS
"Differentiate between checked and unchecked exceptions, with examples."

Two marks, so the examiner wants a table and two named examples — not an essay.

Checked
Unchecked
Compiler's attitude
Insists you catch it or declare it
Says nothing at all
Sits under
Exception, but not RuntimeException
RuntimeException
Caused by
The outside world — a missing file, a dropped connection
A mistake in the code — bad index, null reference, divide by zero
Detected
At compile time
At run time only
Example
IOException
ArithmeticException

The line that proves it

The clearest way to show the difference in an answer is one line of each. The unchecked one compiles; the checked one does not.

1int x = 10 / 0; // unchecked - compiles fine
2FileReader f = new FileReader("marks.txt"); // checked
Unhandled exception type FileNotFoundException
Line 1 is not marked at all. Line 2 is refused before the program can run.

One program showing both

If the question says "with examples", a short program scores better than two names alone.

Creating the file

1Right-click src in Package Explorer → New → Package, name it marks, press Finish. Skip this once the package exists.
2Right-click the marks package → New → Class.
3Type InvalidMarkException in Name, and tick public static void main(String[] args).
4Press Finish. Type the code in, then Ctrl + S to save — Eclipse compiles the moment you save.
5Run it with the green button, or Ctrl + F11.
New Java Class
Source folder:
Unit2Project/src
Package:
marks
Name:
InvalidMarkException
Method stubs:
public static void main(String[] args)
Cancel
Finish

One exception to the rule: do not tick main for an exception class. It is never run on its own — it exists to be thrown by other classes. Tick it for MarkEntry and the rest, which do have a main.

src / marks / BothKinds.java
1public class BothKinds
2{
3 public static void main(String[] args)
4 {
5 // UNCHECKED - compiles, fails only when run
6 try
7 {
8 int x = 10 / 0;
9 }
10 catch (ArithmeticException e)
11 {
12 System.out.println("unchecked : " + e.getMessage());
13 }
14
15 // CHECKED - will not compile unless handled
16 try
17 {
18 throw new Exception("a checked failure");
19 }
20 catch (Exception e)
21 {
22 System.out.println("checked : " + e.getMessage());
23 }
24 }
25}
Console
terminated
<terminated> marks.BothKinds [Java Application]
unchecked : / by zerochecked : a checked failure

The difference is invisible in the output — both were caught and both printed. It shows up in the editor: remove the second try/catch and the file stops compiling, while removing the first changes nothing until the program runs.

What earns both marks

1
State the deciding rule: checked exceptions are enforced by the compiler, unchecked ones are not.
2
Give one named example of eachIOException and ArithmeticException are enough. An unnamed example scores nothing.
A memory hook that survives exam pressure: checked exceptions come from outside your program — a file, a network, a device. Unchecked ones come from inside it — your own arithmetic, your own index, your own null. Outside is checked; inside is your fault.
CHUNK 3 OF 7 0:13 – 0:19

throw and throws

One letter apart, and they do entirely different jobs. This is the most commonly confused pair in the whole topic, so take them one at a time.

throw new Exception("...");
throw is an action. It happens right now, on this line, inside a method body. You are creating an exception object and setting it off deliberately. Singular, and always followed by new.
void check() throws Exception
throws is a warning label. It sits in the method's signature and tells anyone calling it: "this may fail in that way — be ready." Nothing happens when it runs; it is a declaration, not an action.
throw
throws
Where it goes
Inside the method body
In the method's signature
What it does
Sets an exception off now
Declares one might escape
Followed by
One exception object
One or more exception types
How many
One at a time
Several, comma separated
In our code
throw new InvalidMarkException(...) in the body
void post(int v) throws InvalidMarkException on the signature
src / marks / Gate.java  — both words in one small file
1package marks;
2
3public class Gate
4{
5 // "throws" here - a label on the method
6 void checkAge(int age) throws Exception
7 {
8 if (age < 0)
9 {
10 // "throw" here - the action, right now
11 throw new Exception("Age cannot be negative");
12 }
13 System.out.println("Age accepted : " + age);
14 }
15
16 public static void main(String[] args)
17 {
18 Gate gate = new Gate();
19
20 try
21 {
22 gate.checkAge(19);
23 gate.checkAge(-4);
24 }
25 catch (Exception e)
26 {
27 System.out.println("Rejected : " + e.getMessage());
28 }
29 }
30}
Console
terminated
<terminated> marks.Gate [Java Application]
Age accepted : 19Rejected : Age cannot be negative
Code on this page can't be copied — type it out. Typing is where it sticks.
Why does line 6 need throws at all?

Because line 11 throws a plain Exception, which is checked. Remove throws Exception from line 6 and the compiler refuses to build:

Unhandled exception type Exception

The method has two honest options: handle it internally with its own try/catch, or admit it might escape by declaring throws. It cannot stay silent. Had line 11 thrown an unchecked exception instead, no declaration would be needed — which is the practical consequence of chunk 1's split.

CHUNK 4 OF 7 0:19 – 0:26

Writing your own exception

Covering the syllabus phrase: user-defined exceptions

Java's built-in exceptions describe programming faults: bad index, null reference, divide by zero. They have no word for "that admission number does not belong to this college". For rules that belong to your problem, you write your own.

THE WHOLE RECIPE
A custom exception is just a class that extends Exception. Give it a constructor that passes a message up to the parent. That is the entire requirement — there is no special syntax to learn.
src / marks / InvalidMarkException.java  — four lines of real content
1package marks;
2
3public class InvalidMarkException extends Exception
4{
5 InvalidMarkException(String message)
6 {
7 super(message);
8 }
9}
extends Exception This one word makes it a real exception — throwable, catchable, and checked, so the compiler will insist callers deal with it. Extend RuntimeException instead and it becomes unchecked.
the constructor Takes the message you want to attach when this goes wrong.
super(message) Hands the message up to Exception, which already knows how to store it. That is what makes e.getMessage() work later. Without this line the message is simply lost.
ASKED IN CLASS — is super(m) really needed, or is it just ceremony?

It is needed, and here is exactly why. The message is not stored by your class. It is stored by Exception, in a field you cannot reach directly. super(m) is the only way to put it there.

Your constructor
What e.getMessage() gives
super(m);
the message you passed in
left empty
null

Leave it out and the class still compiles and still throws — but every message prints as null, which quietly ruins the output of every exam answer. This is the one place in the unit where super genuinely earns its keep; you will not need it anywhere else here.

If you want no message at all, write the class with no constructor whatsoever and throw it bare. That is simpler, and perfectly valid — but then the catch block can only print text you wrote by hand, not the numbers that caused the failure.

Using it

src / marks / MarkEntry.java
1package marks;
2
3public class MarkEntry
4{
5 void record(int mark) throws InvalidMarkException
6 {
7 if (mark < 0 || mark > 100)
8 {
9 throw new InvalidMarkException(mark + " is not between 0 and 100");
10 }
11 System.out.println("Recorded : " + mark);
12 }
13
14 public static void main(String[] args)
15 {
16 MarkEntry entry = new MarkEntry();
17
18 try
19 {
20 entry.record(78);
21 entry.record(142);
22 entry.record(55);
23 }
24 catch (InvalidMarkException e)
25 {
26 System.out.println("Rejected : " + e.getMessage());
27 }
28 }
29}
Console
terminated
<terminated> marks.MarkEntry [Java Application]
Recorded : 78Rejected : 142 is not between 0 and 100

Line 20 never ran. Same rule as Module 8 — the throw on line 19 abandoned the rest of the try immediately, so 55 was never recorded.

CHUNK 5 OF 7 0:26 – 0:31

Why bother writing your own

You could have used IllegalArgumentException and saved a file. Here is what the custom class buys instead.

The name states the rule. catch (InvalidMarkException e) tells the next reader exactly which rule was broken. catch (Exception e) tells them nothing.
You can catch it separately. A mark out of range and an array fault can now have different responses, because they are different types.
The rule lives in one place. Every part of the program that records a mark throws the same exception, so the rule cannot drift between screens.
Checked means it cannot be forgotten. Extending Exception makes the compiler force every caller to deal with it — a rule that matters is not left to memory.
WHEN TO REACH FOR ONE
When the thing that went wrong is a rule from your problem, not a fault in your code. Marks out of range, insufficient balance, invalid age — all custom. Null reference, bad index, divide by zero — Java already has those, so use them.

Second example — a rule with two ways to fail

src / marks / SeatBooking.java
1package marks;
2
3class SeatFullException extends Exception
4{
5 SeatFullException(String m)
6 {
7 super(m);
8 }
9}
10
11public class SeatBooking
12{
13 static final int CAPACITY = 60;
14
15 int booked = 58;
16
17 void book(int seats) throws SeatFullException
18 {
19 if (booked + seats > CAPACITY)
20 {
21 throw new SeatFullException(
22 "only " + (CAPACITY - booked) + " seats left");
23 }
24 booked = booked + seats;
25 System.out.println(seats + " booked, total now " + booked);
26 }
27
28 public static void main(String[] args)
29 {
30 SeatBooking hall = new SeatBooking();
31
32 try
33 {
34 hall.book(2);
35 hall.book(3);
36 }
37 catch (SeatFullException e)
38 {
39 System.out.println("Booking failed - " + e.getMessage());
40 }
41 }
42}
Console
terminated
<terminated> marks.SeatBooking [Java Application]
2 booked, total now 60Booking failed - only 0 seats left

The message is built at the moment of failure, so it carries the real number. That is why a custom exception takes a String rather than hard-coding its text — a fixed message could not have said "0 seats left".

CHUNK 6 OF 7 0:31 – 0:36

Worked example — custom exception plus multiple catch

Module 8's multiple-catch shape, now with one of your own types alongside a built-in one. This is the pattern Module 10's four-mark questions are built from.

src / marks / Register.java  — complete and runnable
1package marks;
2
3public class Register
4{
5 void enter(int[] list, int slot, int mark)
6 throws InvalidMarkException
7 {
8 if (mark < 0 || mark > 100)
9 {
10 throw new InvalidMarkException(mark + " is out of range");
11 }
12 list[slot] = mark;
13 System.out.println("Slot " + slot + " = " + mark);
14 }
15
16 public static void main(String[] args)
17 {
18 Register reg = new Register();
19 int[] marks = new int[3];
20
21 try
22 {
23 reg.enter(marks, 0, 72);
24 reg.enter(marks, 7, 65); // slot 7 does not exist
25 reg.enter(marks, 1, 180); // never reached
26 }
27 catch (InvalidMarkException e)
28 {
29 System.out.println("Bad mark : " + e.getMessage());
30 }
31 catch (ArrayIndexOutOfBoundsException e)
32 {
33 System.out.println("Bad slot : " + e.getMessage());
34 }
35 finally
36 {
37 System.out.println("-- entry closed --");
38 }
39 }
40}
Console
terminated
<terminated> marks.Register [Java Application]
Slot 0 = 72Bad slot : Index 7 out of bounds for length 3-- entry closed --

Three things to notice, each a rule from earlier in this unit:

One custom type and one built-in type, side by side. A catch block does not care who wrote the exception class.
The second catch ran, not the first. Line 23 threw an array fault, so Java skipped past the InvalidMarkException block to the one that matched.
Line 24 never ran, so the out-of-range mark was never even tested — and finally still closed the entry.
CHUNK 7 OF 7 0:36 – 0:40

Checkpoint

1. Which word goes in each blank?

1static void pay(int amt) ______ InsufficientFundsException 2{ 3 if (amt > balance) ______ new InsufficientFundsException("too much"); 4}
2. Write the complete InsufficientFundsException class.
3. If it extended RuntimeException instead of Exception, what would change?

Show worked solution
1. Line 1 takes throws (the label on the method). Line 3 takes throw (the action, followed by new). The giveaway is new — only throw is ever followed by an object.

2.
1class InsufficientFundsException extends Exception 2{ 3 InsufficientFundsException(String m) 4 { 5 super(m); 6 } 7}
3. It would become unchecked. Line 1's throws would no longer be required, and callers could ignore it entirely — the compiler would stop insisting. For a money rule that is the wrong choice: you want the compiler forcing every caller to think about it.

Carry forward: Module 10 takes this exact class into the four-mark banking question, alongside multiple catch, throws and finally.

Practice

Three problems

Attempt each before opening the solution.
1 Write a custom InvalidAgeException, and a method vote(int age) that throws it below 18 and prints a confirmation otherwise. Call it twice from main to show both outcomes.
Show solution
1class InvalidAgeException extends Exception 2{ 3 InvalidAgeException(String m) 4 { 5 super(m); 6 } 4} 5 6public class Voting 7{ 8 static void vote(int age) throws InvalidAgeException 9 { 10 if (age < 18) 11 { 12 throw new InvalidAgeException(age + " is under 18"); 13 } 14 System.out.println("Vote accepted at age " + age); 15 } 16 17 public static void main(String[] args) 18 { 19 try 20 { 21 vote(21); 22 vote(15); 23 } 24 catch (InvalidAgeException e) 25 { 26 System.out.println("Refused : " + e.getMessage()); 27 } 28 } 29}
Vote accepted at age 21 Refused : 15 is under 18
2 This will not compile. Give the error and two different ways to fix it.
1static void load() 2{ 3 throw new Exception("could not load"); 4}
Show solution
The error: "Unhandled exception type Exception". Exception is checked, so the method must either handle it or declare it — it cannot simply throw and stay silent.

Fix A — declare it, pushing responsibility to the caller:
1static void load() throws Exception
Fix B — handle it here, so nothing escapes:
1static void load() 2{ 3 try 4 { 5 throw new Exception("could not load"); 6 } 7 catch (Exception e) 8 { 9 System.out.println(e.getMessage()); 10 } 11}
Which is right depends on who should decide. If the caller can do something useful about a failed load, declare it. If this method can recover on its own, handle it here.
3 A classmate makes every custom exception extend RuntimeException "so I don't have to write throws everywhere." What is the trade-off they are making?
Show solution
They have traded safety for convenience, and mostly they will regret it.

What they gain: shorter signatures, no throws clauses, no compiler nagging.

What they lose: the compiler no longer forces anyone to think about the failure. A caller who forgets to handle an insufficient-funds case finds out when a real user hits it, not while typing.

The reasonable line: if the rule is one a caller genuinely must handle — money, marks, ages, capacity — extend Exception and let the compiler enforce it. Reserve RuntimeException for faults that mean the code itself is wrong, which is exactly how Java uses it for NullPointerException.

Project so far

Unit2Project
  • m2–m7 school · travel · campus · safety · college
  • marks
    • m8 Average · TwoWays · FinallyDemo · ResultCard
    • new Gate.java
    • new InvalidMarkException.java
    • new MarkEntry.java
    • new SeatBooking.java
    • new Register.java

Module 10 answers the five remaining exception questions in full, using the classes built here.

UP NEXT · MODULE 10
Exception Handling — Integration & Full PYQ Landings
Modules 10–15 arrive in this same file
press ↓ again, or click
Module 10 · Exception Handling — Integration & Full PYQ Landings
0%
40 min
next   back   chunk
MODULE 10 · EXCEPTION HANDLING: INTEGRATION & FULL PYQ LANDINGS · 40 MIN
CHUNK 1 OF 8 0:00 – 0:06

Everything, in one program

Closing the syllabus phrases: Exception Handling — all six sub-topics
Nothing new is taught in this module. Every piece has appeared already — this is where the exam questions get answered in full.

Modules 8 and 9 built the parts separately. This is all of them working at once: a custom exception, a built-in one, multiple catch blocks ordered correctly, throws on the method, and finally closing up.

Creating the file

1Right-click the marks package → New → Class.
2Name it Office and tick public static void main(String[] args).
3Finish, type the code, then Ctrl + S to save and compile.
4Run with the green button, or Ctrl + F11.
src / marks / Office.java  — everything from Modules 8 and 9
1package marks;
2
3public class Office
4{
5 int mark;
6
7 void post(int value) throws InvalidMarkException
8 {
9 if (value < 0 || value > 100)
10 {
11 throw new InvalidMarkException(value + " is out of range");
12 }
13 mark = value;
14 System.out.println("Posted " + mark);
15 }
16
17 public static void main(String[] args)
18 {
19 Office o = new Office();
20
21 try
22 {
23 o.post(74);
24 o.post(210);
25 }
26 catch (InvalidMarkException e)
27 {
28 System.out.println("Rule broken : " + e.getMessage());
29 }
30 finally
31 {
32 System.out.println("-- closed --");
33 }
34 }
35}
Console
terminated
<terminated> marks.Office [Java Application]
Posted 74Rule broken : 210 is out of range-- closed --
Code on this page can't be copied — type it out. Typing is where it sticks.

Six features in one 38-line file: a custom exception, throws, throw, two catch blocks, a built-in exception type, and finally. Every exam question below is a variation on this shape.

CHUNK 2 OF 8 0:06 – 0:11

Exam landing — multiple catch

PYQ · 2 MARKS
"Explain the use of multiple catch blocks for a single try block, with an example."

Two marks: one sentence of explanation, one short program. Keep it small — a long answer wastes time you need elsewhere.

The sentence to write first

1
A single try can fail in several different ways. Each catch handles one type, Java checks them top to bottom, and runs only the first whose type matches.
2
Order them specific first, general last — a general type placed first makes every later block unreachable, which is a compile error.
src / marks / MultiCatch.java  — the whole answer
1public class MultiCatch
2{
3 public static void main(String[] args)
4 {
5 int[] a = new int[2];
6
7 try
8 {
9 a[5] = 10 / 0;
10 }
11 catch (ArithmeticException e)
12 {
13 System.out.println("Arithmetic : " + e.getMessage());
14 }
15 catch (ArrayIndexOutOfBoundsException e)
16 {
17 System.out.println("Bad index : " + e.getMessage());
18 }
19 }
20}
Console
terminated
<terminated> MultiCatch [Java Application]
Arithmetic : / by zero
Line 9 has two faults — why only one message?

a[5] = 10 / 0; has a bad index and a division by zero. Java evaluates the right-hand side first, so the division fails before the index is ever used.

Swap it to a[5] = 10 / 2; and the other catch runs instead. Worth mentioning in the answer if you have room — it shows you know only one exception can be thrown at a time.

CHUNK 3 OF 8 0:11 – 0:18

Exam landing — insurance hierarchy

PYQ · 4 MARKS
"Design a four-class hierarchy in an insurance context that incorporates custom exceptions. Write the complete code along with the terminal output."

Four classes, one hierarchy, one custom exception. Plan it before writing: one parent, two children, one exception class.

Policy abstract · holds the shared rule LifePolicy min cover 50000 VehiclePolicy min cover 20000 LowCoverException thrown by both children
FOUR CLASSES · ONE PARENT, TWO CHILDREN, ONE CUSTOM EXCEPTION
src / insure / Policy.java  — the exception and the parent
1package insure;
2
3class LowCoverException extends Exception
4{
5 LowCoverException(String m)
6 {
7 super(m);
8 }
9}
10
11abstract class Policy
12{
13 abstract int minimum();
14
15 void issue(int amount) throws LowCoverException
16 {
17 if (amount < minimum())
18 {
19 throw new LowCoverException(amount + " is below " + minimum());
20 }
21 System.out.println("Issued for " + amount);
22 }
23}
24
25class PolicyDemo
26{
27 public static void main(String[] args) throws Exception
28 {
29 new VehiclePolicy().issue(35000);
30 }
31}
Console
terminated
<terminated> insure.Insurance [Java Application]
(no output — the driver below runs it)
src / insure / Insurance.java  — two children and the driver
1package insure;
2
3class LifePolicy extends Policy
4{
5 int minimum()
6 {
7 return 50000;
8 }
9}
10
11class VehiclePolicy extends Policy
12{
13 int minimum()
14 {
15 return 20000;
16 }
17}
18
19public class Insurance
20{
21 public static void main(String[] args)
22 {
23 try
24 {
25 new VehiclePolicy().issue(35000);
26 new LifePolicy().issue(30000);
27 }
28 catch (LowCoverException e)
29 {
30 System.out.println("Rejected : " + e.getMessage());
31 }
32 }
33}
Console
terminated
<terminated> insure.Insurance [Java Application]
Issued for 35000Rejected : 30000 is below 50000

Why this scores four marks and a simpler answer would not:

Four classes exactly as asked — exception, abstract parent, two children.
The hierarchy does real work. issue() is written once in the parent but behaves differently per child, because minimum() is abstract. That is Module 3 doing its job here.
Both outcomes are shown — one policy issued, one rejected. An output showing only success proves nothing about the exception.
CHUNK 4 OF 8 0:18 – 0:25

Exam landing — the BankAccount array

PYQ · 4 MARKS
"Write a program using an array of BankAccount objects that demonstrates ArrayIndexOutOfBoundsException, NegativeArraySizeException, ArrayStoreException, a custom InsufficientFundsException, and IllegalArgumentException, handled using multiple catch blocks, throws, and finally."

Five named exceptions in one program. The trick is knowing which line produces each — write that list before you write any code.

NegativeArraySizeException Asking for an array of negative length: new BankAccount[-2]
ArrayIndexOutOfBoundsException Touching a slot that does not exist: list[9] on a array of 3
ArrayStoreException Putting the wrong type into an array: an Object[] that really holds Strings, given a number
IllegalArgumentException A built-in you throw yourself when a value makes no sense — a negative deposit
InsufficientFundsException Your own class, for the rule Java has no word for
src / bank / InsufficientFundsException.java
1package bank;
2
3public class InsufficientFundsException extends Exception
4{
5 InsufficientFundsException(String m)
6 {
7 super(m);
8 }
9}
Console
terminated
<terminated> bank.Branch [Java Application]
(no output — this class is only ever thrown)
src / bank / BankAccount.java  — one field, two rules
1package bank;
2
3public class BankAccount
4{
5 double balance = 5000;
6
7 void deposit(double amount)
8 {
9 if (amount <= 0)
10 {
11 throw new IllegalArgumentException("must be positive");
12 }
13 balance = balance + amount;
14 }
15
16 void withdraw(double amount) throws InsufficientFundsException
17 {
18 if (amount > balance)
19 {
20 throw new InsufficientFundsException("only " + balance);
21 }
22 balance = balance - amount;
23 }
24}
25
26class AccountDemo
27{
28 public static void main(String[] args) throws Exception
29 {
30 BankAccount a = new BankAccount();
31 a.deposit(1500);
32 System.out.println(a.balance);
33 }
34}
Console
terminated
<terminated> bank.Branch [Java Application]
(no output — the driver below runs it)
src / bank / Branch.java  — the driver
1package bank;
2
3public class Branch
4{
5 public static void main(String[] args)
6 {
7 int size = 2; // set to -2 for NegativeArraySizeException
8
9 try
10 {
11 BankAccount[] list = new BankAccount[size];
12 list[0] = new BankAccount();
13
14 list[0].deposit(1500);
15 System.out.println("Balance : " + list[0].balance);
16 list[0].withdraw(9000);
17 }
18 catch (NegativeArraySizeException e)
19 {
20 System.out.println("Bad size : " + e.getMessage());
21 }
22 catch (ArrayIndexOutOfBoundsException e)
23 {
24 System.out.println("Bad slot : " + e.getMessage());
25 }
26 catch (ArrayStoreException e)
27 {
28 System.out.println("Wrong type");
29 }
30 catch (InsufficientFundsException e)
31 {
32 System.out.println("Refused : " + e.getMessage());
33 }
34 catch (IllegalArgumentException e)
35 {
36 System.out.println("Bad amount : " + e.getMessage());
37 }
38 finally
39 {
40 System.out.println("-- closed --");
41 }
42 }
43}
Console
terminated
<terminated> bank.Branch [Java Application]
Balance : 6500.0Refused : only 6500.0-- closed --
Console
terminated
<terminated> bank.Branch [Java Application] — size = -2
Bad size : -2-- branch closed --
The examiner does not expect all five to fire at once — only the first failure in a try ever runs. Write all five catch blocks, then show two runs with one variable changed, exactly as above. Say in one line that changing size, the index, or the amount triggers each in turn.
CHUNK 5 OF 8 0:25 – 0:30

Exam landing — the re-entry loop

PYQ · 4 MARKS
"Write a program that throws a custom InvalidAgeException when a negative age is entered, and re-prompts the user in a loop until a valid age is entered."

The new idea here is not the exception — it is the loop. The try/catch sits inside a loop that keeps going until the input is good.

ask for the age age < 0 ? throw if so caught print, loop again accept & stop the loop is what turns a crash into a second chance
TRY INSIDE THE LOOP · A FAILURE SENDS CONTROL BACK TO THE PROMPT
src / admit / InvalidAgeException.java
1package admit;
2
3public class InvalidAgeException extends Exception
4{
5 InvalidAgeException(String m)
6 {
7 super(m);
8 }
9}
Console
terminated
<terminated> admit.AgeCheck [Java Application]
(no output — thrown by the loop below)
src / admit / AgeCheck.java  — the re-entry loop
1package admit;
2
3import java.util.Scanner;
4
5public class AgeCheck
6{
7 public static void main(String[] args) throws Exception
8 {
9 Scanner sc = new Scanner(System.in);
10 boolean accepted = false;
11
12 while (accepted == false)
13 {
14 System.out.print("Enter age : ");
15 int age = sc.nextInt();
16
17 try
18 {
19 if (age < 0)
20 {
21 throw new InvalidAgeException(age + " is negative");
22 }
23 System.out.println("Accepted : " + age);
24 accepted = true;
25 }
26 catch (InvalidAgeException e)
27 {
28 System.out.println("Rejected : " + e.getMessage());
29 }
30 }
31 sc.close();
32 }
33}
Console
terminated
<terminated> admit.AgeCheck [Java Application]
Enter age : -5Rejected : -5 is negativeEnter age : 19Accepted : 19

Three details the examiner is looking for:

The try is inside the loop, not around it. Put the loop inside the try and one bad entry ends everything.
The flag only turns true on success — line 37 sits after check(), so a throw skips it and the loop repeats.
The output shows the loop working — two rejections then an acceptance. One rejection does not prove it loops.
CHUNK 6 OF 8 0:30 – 0:35

Exam landing — three named types in one program

PYQ · 4 MARKS
"Write a program that catches multiple exceptions using try-catch blocks. Specifically, handle ArithmeticException, ArrayIndexOutOfBoundsException and any user-defined exception."

Three named types, so the program must be able to trigger each one. Drive it from a single variable and show three runs.

src / marks / TooManySubjectsException.java
1package marks;
2
3public class TooManySubjectsException extends Exception
4{
5 TooManySubjectsException(String m)
6 {
7 super(m);
8 }
9}
Console
terminated
<terminated> marks.ThreeKinds [Java Application]
(no output — thrown by the program below)
src / marks / ThreeKinds.java  — one variable, three runs
1package marks;
2
3public class ThreeKinds
4{
5 public static void main(String[] args)
6 {
7 int mode = 1; // try 1, then 2, then 3
8 int[] marks = new int[3];
9
10 try
11 {
12 if (mode == 1) { System.out.println(100 / 0); }
13 if (mode == 2) { System.out.println(marks[7]); }
14 if (mode == 3) { throw new TooManySubjectsException("only 3"); }
15 }
16 catch (ArithmeticException e)
17 {
18 System.out.println("Arithmetic : " + e.getMessage());
19 }
20 catch (ArrayIndexOutOfBoundsException e)
21 {
22 System.out.println("Bad index");
23 }
24 catch (TooManySubjectsException e)
25 {
26 System.out.println("Own rule : " + e.getMessage());
27 }
28 finally
29 {
30 System.out.println("-- done --");
31 }
32 }
33}
Console
terminated
<terminated> marks.ThreeKinds [Java Application] — mode 1, 2, 3
Arithmetic : / by zero-- done -- Bad index-- done -- Own rule : only 3-- done --

One variable, three runs, three different catch blocks — and finally printing on every one. Writing it this way lets a four-mark answer demonstrate all three types without needing three separate programs.

CHUNK 7 OF 8 0:35 – 0:38

The two habits to avoid

1. Catching Exception for everything

1try { ...a hundred lines... }
2catch (Exception e) { System.out.println("error"); }
Compiles, runs, and tells you nothing
Which line failed? Which rule broke? The message is gone.

It also blocks anything below it — place it first and every specific catch after becomes an unreachable-block error. Catch the narrowest type that fits, and wrap only the lines that can actually fail.

2. The empty catch block

1catch (InsufficientFundsException e) { }
The withdrawal silently did not happen
No message, no crash, no record. The customer is told nothing.

This is worse than the crash it replaces. A crash at least tells you something went wrong; an empty catch hides it and the program carries on as though the work was done.

The minimum a catch block should do is say what happened, using e.getMessage(). If you genuinely have nothing to do about a failure, that is a sign the exception should be declared with throws and handled by whoever called you.
CHUNK 8 OF 8 0:38 – 0:40

Teach-back — closing Exception Handling

Say each answer aloud before opening it. If you can name the hinge of each question, you can plan any exception answer in the hall.

Which single idea does each question hinge on?
1. Multiple catch for one try  ·  2. Insurance hierarchy  ·  3. BankAccount array
4. Invalid age loop  ·  5. Three named types  ·  6. Checked vs unchecked

Show answers
1. Order. Specific before general, first match wins, only one runs.

2. The abstract parent. One issue() method serves both children because minimum() is abstract — Module 3 carrying the weight.

3. Knowing which line throws which type. Five names, five causes; the catch blocks are the easy part.

4. The try sits inside the loop. That single placement is what turns a rejection into a re-prompt.

5. One driver variable. Three runs from one program beats three programs.

6. Who enforces it. The compiler insists on checked exceptions and stays silent about unchecked ones.

Exception Handling is complete. All six syllabus sub-topics and six previous-year questions are covered. Module 11 opens Multithreaded Programming.

Practice

Two problems

Longer than usual, because these are exam-sized.
1 Rewrite the insurance answer with a third child class HealthPolicy whose minimum is 30000, and show the output when it is issued 25000.
Show solution
Add one class — nothing else changes, which is the point of the abstract parent:
1class HealthPolicy extends Policy 2{ 3 int minimum() 4 { 5 return 30000; 6 } 7}
Then in main:
1Policy health = new HealthPolicy(); 2health.issue(25000);
Rejected : 25000 is below the minimum 30000 -- counter closed --
Note what you did not have to write: no new issue(), no new exception, no new catch block. Adding a policy type costs one method.
2 In the BankAccount program, what change triggers ArrayStoreException, and why can it not happen in the version shown?
Show solution
It cannot happen as written, because list is declared BankAccount[] and only BankAccount objects are ever stored in it. The compiler would reject anything else before the program ran.

To trigger it you need an array whose declared type is wider than its real type:
1Object[] slots = new String[2]; // really a String array 2slots[0] = "Asha"; // fine 3slots[1] = new BankAccount("Ravi", 100); // throws
Wrong type : bank.BankAccount
Why line 3 compiles but fails: the compiler only checks the declared type, Object[], and a BankAccount is an Object. Only at run time does Java see the array is really a String[] and refuse. Worth one line in the answer — it shows you know why this exception exists at all.

Project so far

Unit2Project
  • m2–m7 school · travel · campus · safety · college
  • m8–m9 marks / Average · TwoWays · FinallyDemo · ResultCard · Gate · MarkEntry · SeatBooking · Register
  • new this module
    • new marks / Office.java · MultiCatch.java · ThreeKinds.java
    • new insure / Insurance.java
    • new bank / Branch.java
    • new admit / AgeCheck.java

Exception Handling is finished. Module 11 begins Multithreaded Programming with a fresh package.

UP NEXT · MODULE 11
Multithreading — Fundamentals
Modules 11–15 arrive in this same file
press ↓ again, or click
Module 11 · Multithreading — Fundamentals
0%
40 min
next   back   chunk
MODULE 11 · MULTITHREADING: FUNDAMENTALS · 40 MIN
CHUNK 1 OF 6 0:00 – 0:07

More than one thing at a time

Covering the syllabus phrase: Multithreaded Programming — introduction to threads
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Every program you have written so far did one thing, then the next, then the next. One line finished before the following line began.

A thread is a second line of execution inside the same program, running at the same time as the first.

The kitchen

Picture a college canteen kitchen.

One cook chops, then boils, then serves. Nothing overlaps. If the boiling takes ten minutes, nobody is served for ten minutes.
Three cooks in that same kitchen work at once, sharing the same counters, the same fridge, the same knives. Serving carries on while something boils.
A second kitchen down the road also cooks at once — but it has its own fridge, its own counters, its own everything. Nothing is shared.
THE MAPPING
The kitchen is a process — a running program with its own memory. Each cook is a thread inside it, sharing that memory with the others. The second kitchen is a second process, sharing nothing.

Why reach for a second thread at all

Waiting stops blocking everything. While one thread waits on a file or a network, another keeps working. The program stays responsive.
Independent jobs overlap. Chopping and washing need not take turns — two cooks finish sooner than one doing both.
They are cheap. Threads share the process memory, so creating one costs far less than starting a whole new program.
Sharing is direct. Two threads read the same variable with no special machinery — as the program above showed.
WHEN NOT TO
If the work is short and strictly sequential, one thread is simpler and faster. Threads only pay off when something genuinely waits, or when independent jobs can overlap. Added carelessly they bring the bugs of Module 12 for no gain.

Exam landing

PYQ · 2 MARKS
"Differentiate between Thread and Process."
Process
Thread
What it is
A running program
One path of execution inside a program
Memory
Its own separate space
Shares the memory of its process
Switching between them
Heavy — the whole context changes
Light — far less to swap
Talking to each other
Needs help from the operating system
Direct, through shared variables
If one crashes
Others are unaffected
The whole process can go down
Cost to create
Expensive
Cheap

Showing the shared memory in one program

The table above is the answer; this proves the middle row. Both threads read and change the same plates variable, which two separate processes could never do.

src / kitchen / OneProcess.java  — two threads, one memory
1package kitchen;
2
3public class OneProcess extends Thread
4{
5 static int plates = 0; // shared by every thread
6
7 public void run()
8 {
9 plates = plates + 1;
10 System.out.println(Thread.currentThread().getName()
11 + " sees " + plates);
12 }
13
14 public static void main(String[] args)
15 {
16 new OneProcess().start();
17 new OneProcess().start();
18 }
19}
Console
terminated
<terminated> kitchen.OneProcess — one run — the order and values can change between runs
Thread-0 sees 2Thread-1 sees 2

In this run both threads printed 2: each added 1 to the same shared plates, so each saw the other's change too. Another run can print the lines in the other order, or show 1 and 2. Separate processes each get their own copy and would both print 1. That sharing is the convenience — and, from Module 12 onward, the danger.

Two marks wants the memory row above all. Separate memory for processes, shared memory for threads. Say that first, add one more row, and you have the marks. The sharing is also where all the trouble starts — Module 12 is entirely about it.
CHUNK 2 OF 6 0:07 – 0:15
The word for swapping threads. When the system pauses one thread to let another run, that swap is a context switch — it must save where the first thread was and restore where the second left off. Between threads this is cheap, since they share memory; between processes it is expensive, because everything changes. That cost difference is the row worth quoting in the Thread vs Process answer.

Making one, by extending Thread

Covering the syllabus phrases: creating threads and extending the Thread class

Creating the file

1Right-click srcNew → Package, name it kitchen, press Finish.
2Right-click kitchenNew → Class, name it Cook, tick public static void main(String[] args).
3Finish, type the code, Ctrl + S to save and compile, then the green to run.

Two steps only: say your class is a Thread, and write what it should do inside run().

src / kitchen / Cook.java
1package kitchen;
2
3public class Cook extends Thread
4{
5 public void run()
6 {
7 System.out.println("Chopping onions");
8 }
9
10 public static void main(String[] args)
11 {
12 Cook c = new Cook();
13 c.start();
14 System.out.println("Main carries on");
15 }
16}
Console
terminated
<terminated> kitchen.Cook [Java Application]
Main carries onChopping onions
Code on this page can't be copied — type it out. Typing is where it sticks.
Why did line 14 print before line 7?

Because start() does not wait. It hands the work to a new thread and returns straight away, so main reaches line 14 while the cook is still getting going.

Run it a few times. The order may swap. That is not a bug — with two threads running, neither is promised to finish first. Getting comfortable with that uncertainty is most of what this module is for.

extends Thread Your class becomes a kind of thread, inheriting start() and everything else Java already wrote.
run() The work this thread should do. You write it; you never call it yourself.
start() The one you do call. It creates the new thread and that thread then calls your run().

PYQ · 4 marks — "With a suitable example, explain how to create threads using the Thread class."

1
Write the class with extends Thread.
2
Override run() with the work.
3
Create an object and call start() — never run().
4
Show the output, and say in one line that the order may vary between runs.
CHUNK 3 OF 6 0:15 – 0:22

The second way — implementing Runnable

Covering the syllabus phrase: implementing the Runnable interface

Same job, written differently. Instead of being a thread, your class describes work and hands it to a thread.

src / kitchen / Washer.java
1package kitchen;
2
3public class Washer implements Runnable
4{
5 public void run()
6 {
7 System.out.println("Washing plates");
8 }
9
10 public static void main(String[] args)
11 {
12 Washer w = new Washer();
13 Thread t = new Thread(w);
14 t.start();
15 }
16}
Console
terminated
<terminated> kitchen.Washer [Java Application]
Washing plates

Line 13 is the only real difference: the work is handed to a Thread, and that thread is started.

Which should you use?

extends Thread
implements Runnable
Your class is
a thread
work that a thread can run
Starting it
c.start()
new Thread(w).start()
Can it extend something else?
No — the one parent is used up
Yes — it is only an interface
Typical use
quick examples
real programs
In our code
Cook extends Thread
Washer implements Runnable
WHY RUNNABLE WINS
Module 5's rule decides it: a class gets one parent but any number of interfaces. Spend the parent on Thread and the class can never extend anything else. Runnable costs nothing and leaves that choice open, which is why real code prefers it.
CHUNK 4 OF 6 0:22 – 0:28

Worked example — two cooks at once

One thread proves nothing. Two threads running together show the thing that makes this topic different from everything before it.

src / kitchen / TwoCooks.java
1package kitchen;
2
3public class TwoCooks extends Thread
4{
5 String job;
6
7 public void run()
8 {
9 for (int i = 1; i <= 3; i++)
10 {
11 System.out.println(job + " " + i);
12 }
13 }
14
15 public static void main(String[] args)
16 {
17 TwoCooks a = new TwoCooks();
18 TwoCooks b = new TwoCooks();
19
20 a.job = "Chop";
21 b.job = "Wash";
22
23 a.start();
24 b.start();
25 }
26}
Console
terminated
<terminated> kitchen.TwoCooks [Java Application] — one run
Chop 1Wash 1Chop 2Chop 3Wash 2Wash 3
Console
terminated
<terminated> kitchen.TwoCooks [Java Application] — the very next run
Chop 1Chop 2Chop 3Wash 1Wash 2Wash 3
Two runs, two different outputs, same unchanged code. Nothing is broken. The two threads take turns in whatever order the system happens to give them, and that order is not yours to control. Everything difficult about threads follows from this one fact.

Your own output will differ again. Run it five times and note how many distinct orderings you see — that is a better lesson than any explanation.

CHUNK 5 OF 6 0:28 – 0:35

The life of a thread

Covering the syllabus phrase: life cycle of a thread

A thread passes through five states. Each move is caused by a specific event, and naming those events is what the exam question wants.

New object made start() Runnable waiting its turn chosen Running run() executing paused Blocked / Waiting sleep() · wait() pauses wait over run() ends Terminated cannot restart Runnable and Running swap back and forth many times before a thread ends
FIVE STATES · EACH ARROW IS THE EVENT THAT CAUSES THE MOVE
New The object exists, start() has not been called. It is not running and never will unless you start it.
Runnable start() has been called. It is ready and waiting for the system to give it a turn.
Running The system picked it, and run() is executing now.
Blocked / Waiting Paused on purpose — by sleep(), or waiting for something another thread holds. It returns to Runnable when the wait ends.
Terminated run() finished. The thread is done for good — calling start() again throws an exception.

The mistake that hides the whole topic

Call run() yourself instead of start() and everything still compiles, still prints, and looks correct. But no thread was ever created.

src / kitchen / WrongWay.java
1package kitchen;
2
3public class WrongWay extends Thread
4{
5 public void run()
6 {
7 System.out.println(Thread.currentThread().getName());
8 }
9
10 public static void main(String[] args)
11 {
12 new WrongWay().run(); // no new thread
13 new WrongWay().start(); // a real thread
14 }
15}
Console
terminated
<terminated> kitchen.WrongWay [Java Application]
mainThread-1

The output names the culprit. Line 12 printed main — it ran on the main thread, like any ordinary method call. Line 13 printed Thread-1, a genuinely new thread. Printing the thread's name is the quickest way to prove which one you actually got.

PYQ · 4 marks — "Briefly explain the life cycle of a thread."

1
Draw the five states in order and label each arrow with the event causing it. The diagram carries most of the marks.
2
One line per state — what it means, and what moves the thread onward.
3
Say that Runnable and Running alternate many times. Answers that draw a single straight line miss this.
4
End with Terminated being final — a finished thread cannot be started again.
CHUNK 6 OF 6 0:35 – 0:40

Checkpoint

1. What does this print, and why is that a trick question?

1Cook a = new Cook(); 2a.start(); 3System.out.println("done");
2. Name the five states in order.
3. Why does real code usually prefer Runnable over extends Thread?

Show worked solution
1. There is no single right answer — that is the trick. It prints Chopping onions and done, but either order is possible. start() returns immediately, so line 3 often wins. Any answer claiming one fixed order has missed the point of the module.

2. New → Runnable → Running → Blocked/Waiting → Terminated. Running and Runnable swap back and forth many times; Terminated is final.

3. A class has one parent but many interfaces. extends Thread spends the parent and blocks the class from extending anything else. Runnable leaves that free.

Carry forward: Module 12 takes the two cooks from Chunk 4 and gives them something to share — which is where the real difficulty of threads begins.

Practice

Three problems

Attempt each before opening the solution.
1 Write a Server class using Runnable that prints "Serving table" five times. Start two of them from main.
Show solution
1public class Server implements Runnable 2{ 3 public void run() 4 { 5 for (int i = 1; i <= 5; i++) 6 { 7 System.out.println("Serving table " + i); 8 } 9 } 10 11 public static void main(String[] args) 12 { 13 new Thread(new Server()).start(); 14 new Thread(new Server()).start(); 15 } 16}
The two sets of five lines will interleave differently each run.
2 A classmate says their threaded program "works perfectly and always prints in the right order". What would you check first?
Show solution
Check whether they called run() instead of start(). That is the usual cause of suspiciously tidy output — the work ran on the main thread as an ordinary method call, so of course the order is perfect. No thread was ever created.

The quickest proof is one line inside run():
1System.out.println(Thread.currentThread().getName());
If it prints main, there is no second thread. A real one prints Thread-0, Thread-1 and so on.
3 Which state is a thread in at each of these moments? (a) after new Cook() (b) after start() but before it gets a turn (c) during sleep() (d) after run() returns
Show solution
(a) New. The object exists but nothing is scheduled.

(b) Runnable. Ready and queued — note this is not Running. The system decides when.

(c) Blocked / Waiting. It returns to Runnable when the sleep ends, not straight back to Running.

(d) Terminated. Permanent — calling start() on it again throws IllegalThreadStateException.

The distinction worth keeping: Runnable means allowed to run, Running means running right now. Most answers that lose marks confuse these two.

Project so far

Unit2Project
  • m2–m7 school · travel · campus · safety · college
  • m8–m10 marks · insure · bank · admit
  • kitchen — new this module
    • new Cook.java
    • new Washer.java
    • new TwoCooks.java
    • new WrongWay.java

Module 12 keeps the kitchen package and gives the cooks one shared thing to fight over.

UP NEXT · MODULE 12
Multithreading — Priority & Synchronization
Modules 12–15 arrive in this same file
press ↓ again, or click
Module 12 · Multithreading — Priority & Synchronization
0%
40 min
next   back   chunk
MODULE 12 · MULTITHREADING: PRIORITY & SYNCHRONIZATION · 40 MIN
CHUNK 1 OF 6 0:00 – 0:07

Priority, and asking a thread to wait

Covering the syllabus phrase: priority of a thread
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Module 11 ended on an uncomfortable fact: the order two threads run in is not yours to choose. Java gives you two things that influence it, and it is worth being clear that only one of them actually works.

setPriority(n) — a hint, from 1 to 10. You are suggesting which thread matters more. The system may act on it, or ignore it entirely.
Thread.sleep(ms)sleep() guarantees that this thread pauses for at least that long. It does not decide which thread runs next, so the order can change from run to run.
src / kitchen / PriorityDemo.java
1package kitchen;
2
3public class PriorityDemo
4{
5 public static void main(String[] args)
6 {
7 Thread t = new Thread();
8 System.out.println("Default priority: " + t.getPriority());
9
10 t.setPriority(Thread.MAX_PRIORITY);
11 System.out.println("After setPriority: " + t.getPriority());
12
13 System.out.println("MIN_PRIORITY = " + Thread.MIN_PRIORITY);
14 System.out.println("NORM_PRIORITY = " + Thread.NORM_PRIORITY);
15 System.out.println("MAX_PRIORITY = " + Thread.MAX_PRIORITY);
16 }
17}
Console
terminated
<terminated> kitchen.PriorityDemo [Java Application]
Default priority: 5After setPriority: 10MIN_PRIORITY = 1NORM_PRIORITY = 5MAX_PRIORITY = 10

Priority is a hint to the scheduler, not a promise about order.

Creating the file

1Right-click the kitchen package → New → Class, name it Paced, tick public static void main(String[] args).
2Finish, type the code, Ctrl + S to save, then the green to run.
src / kitchen / Paced.java
1package kitchen;
2
3public class Paced extends Thread
4{
5 String job;
6
7 public void run()
8 {
9 for (int i = 1; i <= 3; i++)
10 {
11 System.out.println(job + " " + i);
12 try
13 {
14 Thread.sleep(200);
15 }
16 catch (InterruptedException e)
17 {
18 System.out.println("woken early");
19 }
20 }
21 }
22
23 public static void main(String[] args)
24 {
25 Paced a = new Paced();
26 Paced b = new Paced();
27
28 a.job = "Chop";
29 b.job = "Wash";
30
31 a.start();
32 b.start();
33 }
34}
Console
terminated
<terminated> kitchen.Paced [Java Application]
Chop 1Wash 1Chop 2Wash 2Chop 3Wash 3
Code on this page can't be copied — type it out. Typing is where it sticks.

Compare this with Module 11's messy interleaving. Each thread steps aside for 200ms after printing, which spreads the lines out. sleep() guarantees that this thread pauses for at least that long. It does not decide which thread runs next, so the order can change from run to run. The console shows one real run.

Do not trust priority to fix anything. Setting a.setPriority(10) and b.setPriority(1) may change the order on your laptop and change nothing in the lab. If your program only works at certain priorities, it is broken — the next chunk shows what actually goes wrong.

sleep() must be wrapped in try/catch because it throws a checked InterruptedException — Module 9's rule, met here in real code for the first time.

CHUNK 2 OF 6 0:07 – 0:16

Two people, one seat

You have booked a cinema seat online. So has everyone. Now picture two people tapping seat A4 at the same instant.

SCREEN Row A A1 A2 A3 A4 free — for now Asha taps A4 Ravi taps A4 both read "free" before either writes "booked"
TWO THREADS · ONE SEAT · BOTH LOOK BEFORE EITHER ACTS

Booking a seat is two steps, not one: check whether it is free, then mark it taken. If a second thread checks in the gap between those two steps, it also sees "free".

src / cinema / Booking.java  — no protection
1package cinema;
2
3public class Booking extends Thread
4{
5 static boolean seatTaken = false;
6 String user;
7
8 public void run()
9 {
10 if (seatTaken == false) // step 1 : look
11 {
12 try
13 {
14 Thread.sleep(50);
15 }
16 catch (InterruptedException e)
17 {
18 System.out.println(e.getMessage());
19 }
20 seatTaken = true; // step 2 : take
21 System.out.println(user + " booked A4");
22 }
23 else
24 {
25 System.out.println(user + " : already booked");
26 }
27 }
28
29 public static void main(String[] args)
30 {
31 Booking a = new Booking();
32 Booking b = new Booking();
33
34 a.user = "Asha";
35 b.user = "Ravi";
36
37 a.start();
38 b.start();
39 }
40}
Console
terminated
<terminated> cinema.Booking — a typical run
Asha booked A4Ravi booked A4
This output is the whole problem. Two people hold the same seat. The code is not wrong on any single line — it is wrong because two threads got between line 10 and line 20. This is called a race condition.

The pause on line 14 widens the gap between the look and the take, so both threads usually pass line 10 before either reaches line 20. Without the pause the same race still exists, but it shows up rarely — which is exactly what makes these bugs expensive: they pass every test, then happen on a busy Friday evening.

CHUNK 3 OF 6 0:16 – 0:24

The fix — one word

Covering the syllabus phrase: synchronization
SYNCHRONIZED
Marking a method synchronized means only one thread may be inside it at a time. Any other thread that arrives waits at the door until the first one leaves.

The look-then-take pair can no longer be split, because a second thread cannot get in halfway.

src / cinema / SafeBooking.java  — one word changed
1package cinema;
2
3public class SafeBooking extends Thread
4{
5 static boolean seatTaken = false;
6 String user;
7
8 static synchronized void book(String who)
9 {
10 if (seatTaken == false)
11 {
12 try
13 {
14 Thread.sleep(50);
15 }
16 catch (InterruptedException e)
17 {
18 System.out.println(e.getMessage());
19 }
20 seatTaken = true;
21 System.out.println(who + " booked A4");
22 }
23 else
24 {
25 System.out.println(who + " : already booked");
26 }
27 }
28
29 public void run()
30 {
31 book(user);
32 }
33
34 public static void main(String[] args)
35 {
36 SafeBooking a = new SafeBooking();
37 SafeBooking b = new SafeBooking();
38
39 a.user = "Asha";
40 b.user = "Ravi";
41
42 a.start();
43 b.start();
44 }
45}
Console
terminated
<terminated> cinema.SafeBooking — one real run
Asha booked A4Ravi : already booked

Two things changed, and only one of them matters:

The word synchronized on line 8. This is the fix. One thread inside book() at a time, so nobody can look while somebody else is taking.
The work moved into its own method. Not required, but synchronized guards a method, so the two steps that must stay together need to live in one.
Who books first is still unpredictable — Ravi may win instead. What is now guaranteed is that exactly one of them does.
Without synchronized
With it
Typical run of our code
two bookings, same seat
one booking
Without the pause
usually one booking, sometimes two
still one booking
Who gets it
unpredictable
unpredictable — and that is fine
Cost
none
one thread waits briefly
In our code
Booking.java — Asha and Ravi both get A4
SafeBooking.java — Ravi is told it is gone
CHUNK 4 OF 6 0:24 – 0:30

Settling a question from Module 2

Module 2 left something open. getInstance() checks whether the monitor exists, and builds one if not — look, then take. The same shape as the seat.

So what happens if two threads call it at the same instant? Both see an empty slot, and both build a monitor. The Singleton quietly stops being single.

src / school / SafeMonitor.java  — one word added
1package school;
2
3public class SafeMonitor
4{
5 private static SafeMonitor theMonitor;
6
7 private SafeMonitor()
8 {
9 System.out.println("A monitor was appointed");
10 }
11
12 public static synchronized SafeMonitor getInstance()
13 {
14 if (theMonitor == null)
15 {
16 theMonitor = new SafeMonitor();
17 }
18 return theMonitor;
19 }
20
21 public static void main(String[] args)
22 {
23 getInstance();
24 getInstance();
25 }
26}
Console
terminated
<terminated> school.SafeMonitor [Java Application]
A monitor was appointed

One line printed, from two calls. That was already true in Module 2 with a single thread. synchronized is what keeps it true when several threads call at once.

Worth saying in a Singleton answer. "The lazy version is not thread-safe unless getInstance() is synchronized" is one line that shows you understand the pattern rather than just reciting it — and it connects two syllabus topics, which examiners notice.
CHUNK 5 OF 6 0:30 – 0:35
The word for code that survives this. A method several threads can call at once without the data going wrong is thread safe. SafeBooking.book() is thread safe; Booking.run() is not. Saying a method "is thread safe" is the compact way to claim exactly what synchronized bought you.

Exam landing

PYQ · 2 MARKS
"Explain the significance of thread synchronization in Java."

A two-mark answer, in three sentences

1
State the problem. Threads share memory, so two can read and change the same data at once, leaving it wrong. This is a race condition.
2
State the mechanism. synchronized allows only one thread inside a method at a time; the others wait.
3
Give the example. Two users booking one cinema seat: without it both bookings succeed; with it exactly one does.

The program to write with the answer

One seat, two threads. Remove synchronized from line 6 and both can print got it, leaving seats at −1.

src / cinema / WhySync.java  — the answer as one program
1package cinema;
2
3public class WhySync extends Thread
4{
5 static int seats = 1;
6
7 static synchronized void book(String who)
8 {
9 if (seats > 0)
10 {
11 seats = seats - 1;
12 System.out.println(who + " got it");
13 }
14 else
15 {
16 System.out.println(who + " : sold out");
17 }
18 }
19
20 public void run()
21 {
22 book(Thread.currentThread().getName());
23 }
24
25 public static void main(String[] args)
26 {
27 new WhySync().start();
28 new WhySync().start();
29 }
30}
Console
terminated
<terminated> cinema.WhySync [Java Application]
Thread-0 got itThread-1 : sold out

Say in one line that without the keyword the count can go negative. A negative number of seats is the kind of concrete wrongness that earns the second mark.

Why it earns its place

Shared data stays correct. A check and the action following it cannot be split apart by another thread.
Rare bugs stop existing. The double booking that appears once in a thousand runs is the worst kind, because testing misses it.
It costs almost nothing here. One thread waits a moment. Compare that to two people holding the same seat.
WHEN TO REACH FOR IT
Whenever more than one thread can change the same data. If threads only ever read, no synchronization is needed. Marking everything synchronized is not "safer" — it makes threads queue for no reason, and Module 13 shows how that leads to something worse.
CHUNK 6 OF 6 0:35 – 0:40

Checkpoint — find the bug

Two threads run this. It usually prints 200. Sometimes it prints less.

1static int count = 0; 2 3static void bump() 4{ 5 for (int i = 0; i < 100; i++) 6 { 7 count = count + 1; 8 } 9}

1. Why can the total come out below 200?
2. What one word fixes it, and where?
3. Would making count final help?

Show worked solution
1. Line 7 looks like one step but is three: read count, add one, write it back. If both threads read 40 before either writes, both write 41 — two increments, one gained. Exactly the seat problem with a number instead of a seat.

2. static synchronized void bump(). One thread completes its whole loop before the other starts, so no read can land between another thread's read and write.

3. No, and it would not compile. final means the value can never change — but the whole point is to change it. final answers "may this change?"; synchronized answers "who may change it, and when?" Different questions, as Module 7 put it.

Carry forward: Module 13 asks what happens when two threads each hold something the other is waiting for — and neither will let go.

Practice

Three problems

Attempt each before opening the solution.
1 Write a Counter class where two threads each add 1000 to a shared total, safely. Print the total at the end.
Show solution
1public class Counter extends Thread 2{ 3 static int total = 0; 4 5 static synchronized void add() 6 { 7 total = total + 1; 8 } 9 10 public void run() 11 { 12 for (int i = 0; i < 1000; i++) 13 { 14 add(); 15 } 16 } 17 18 public static void main(String[] args) throws Exception 19 { 20 Counter a = new Counter(); 21 Counter b = new Counter(); 22 23 a.start(); 24 b.start(); 25 26 a.join(); 27 b.join(); 28 29 System.out.println(total); 30 } 31}
2000
Lines 26 and 27 matter. join() makes main wait for each thread to finish. Without them, main prints the total while the threads are still counting — and you get some number below 2000 for a completely different reason.
2 A classmate says: "I ran the booking program twenty times and it never double-booked, so it is fine without synchronized." What do you say?
Show solution
Twenty clean runs prove nothing. A race condition needs the two threads to land in a very narrow window — a few instructions wide. On a quiet machine that may not happen in a thousand runs.

The bug is in the code, not in the output. The check on line 10 and the write on line 20 are separable, and that is enough to make it wrong. Whether it has failed yet is luck.

What actually changes the odds: a busier machine, more threads, a slower moment between the two lines. Which is to say, real users on a real evening.
3 Should a method that only reads shared data be synchronized? Explain.
Show solution
Generally no. A race needs at least one writer. If every thread only reads, nobody can leave the data half-changed, so there is nothing to protect.

The cost of over-using it is that threads queue up for no benefit, which throws away the reason you used threads at all.

The honest caveat: "only reads" must be true of every thread. One writer elsewhere and the readers can see half-finished data, at which point they need protecting too.

Project so far

Unit2Project
  • m2–m7 school · travel · campus · safety · college
  • m8–m10 marks · insure · bank · admit
  • m11 kitchen / Cook · Washer · TwoCooks · WrongWay · OneProcess
  • new this module
    • new kitchen / Paced.java
    • new cinema / Booking.java
    • new cinema / SafeBooking.java
    • new school / SafeMonitor.java

Module 13 closes Multithreaded Programming with inter-thread communication and deadlock.

UP NEXT · MODULE 13
Inter-thread Communication & Deadlock
Modules 13–15 arrive in this same file
press ↓ again, or click
Module 13 · Inter-thread Communication & Deadlock
0%
40 min
next   back   chunk
MODULE 13 · INTER-THREAD COMMUNICATION & DEADLOCK · 40 MIN
CHUNK 1 OF 6 0:00 – 0:08

Threads that wait for each other

Covering the syllabus phrase: inter-thread communication
Concept first — nothing to solve on this page. Read it through; the exercises come after the teaching.

Module 12 stopped two threads colliding. This module handles a different situation: one thread has nothing to do until another thread does something.

The problem, in the canteen

A cook makes one plate at a time. A server takes plates away. What should the server do when the counter is empty?

Keep checking — ask "is there a plate?" over and over. It works, and it wastes the processor doing nothing. This is called busy waiting.
Step aside and be told — wait quietly, and let the cook tap you on the shoulder when a plate is ready. This is what wait() and notify() are for.
wait() "I cannot continue yet." The thread steps aside and releases the lock so somebody else can get in. It stays out until notified.
notify() "Something changed." Wakes one waiting thread. It does not hand over immediately — the woken thread rejoins the queue for the lock.
notifyAll() Wakes every waiting thread. Safer when several are waiting for different reasons; each rechecks its own condition.
THE RULE
All three may only be called from inside a synchronized method or block. Call one outside and the program compiles, then throws IllegalMonitorStateException the moment it runs.
Why that rule exists, in one line: wait() releases a lock, so it must be holding one first. You cannot let go of something you never picked up.
CHUNK 2 OF 6 0:08 – 0:18

Worked example — one cook, one server

Creating the files

1Right-click the kitchen package → New → Class, name it Counter. Leave main unticked — it is shared data, not a program.
2Make a second class Canteen, this time with main ticked.
3Ctrl + S to save each, then run Canteen with the green .

The counter holds one plate. The cook puts a plate down; the server picks it up. Neither may act when it is the other's turn.

src / kitchen / Counter.java  — the shared counter
1package kitchen;
2
3public class Counter
4{
5 boolean plateReady = false;
6
7 synchronized void putPlate() throws Exception
8 {
9 while (plateReady == true)
10 {
11 wait(); // counter full, step aside
12 }
13 plateReady = true;
14 System.out.println("Cook : plate down");
15 notify();
16 }
17
18 synchronized void takePlate() throws Exception
19 {
20 while (plateReady == false)
21 {
22 wait(); // nothing there, step aside
23 }
24 plateReady = false;
25 System.out.println("Server : plate taken");
26 notify();
27 }
28
29 public static void main(String[] args) throws Exception
30 {
31 Counter c = new Counter();
32 c.putPlate();
33 c.takePlate();
34 }
35}
Console
terminated
<terminated> kitchen.Canteen [Java Application]
Cook : plate downServer : plate taken
Code on this page can't be copied — type it out. Typing is where it sticks.
src / kitchen / Canteen.java  — three plates, start to finish
1package kitchen;
2
3public class Canteen
4{
5 public static void main(String[] args)
6 {
7 Counter c = new Counter();
8
9 Thread cook = new Thread()
10 {
11 public void run()
12 {
13 try
14 {
15 c.putPlate();
16 }
17 catch (Exception e)
18 {
19 System.out.println(e.getMessage());
20 }
21 }
22 };
23
24 Thread server = new Thread()
25 {
26 public void run()
27 {
28 try
29 {
30 c.takePlate();
31 }
32 catch (Exception e)
33 {
34 System.out.println(e.getMessage());
35 }
36 }
37 };
38
39 server.start(); // starts first, but must wait
40 cook.start();
41 }
42}
Console
terminated
<terminated> kitchen.Canteen [Java Application]
Cook : plate downServer : plate taken
The server started first and still printed second. It found an empty counter, called wait(), and stepped aside. The cook then put a plate down and notified. Order is no longer luck — it is the condition deciding.
Why while on lines 9 and 20, and not if?

Because being notified does not guarantee the condition is still true. Another thread may get in first and take the plate again before this one resumes.

while makes the thread recheck after waking. if checks once and then trusts, which is how this pattern quietly breaks with more than two threads.

Remember it as: wait in a loop, never in an if. It is one word, and it is the difference between code that works with two threads and code that works with any number.

Why wait() beats checking in a loop

A server could just keep asking "is there a plate?" forever. Here is what stepping aside buys instead.

The processor is left alone. A waiting thread uses nothing. A thread spinning on a check burns a core asking a question whose answer has not changed.
The lock is released. wait() lets go, so the other thread can actually get in and change the thing being waited for. A spin loop inside synchronized would hold the door shut and wait forever.
Waking is immediate. notify() tells the waiting thread the moment something changes, rather than up to a whole polling interval later.
The intent is readable. while (empty) wait(); says plainly what the thread needs. A spin loop says only that it is busy.
WHEN TO REACH FOR IT
Whenever one thread cannot proceed until another changes something. If threads never need to wait on each other, synchronized alone is enough — wait() and notify() add machinery you would not need.
CHUNK 3 OF 6 0:18 – 0:26
The textbook name for the cook and the server. One thread making things and another consuming them, with a shared buffer between, is the producer-consumer problem — the standard example for wait() and notify(). Checking in a loop instead of waiting is called busy waiting or spinning. Both names are worth using in an answer.

Deadlock — both waiting, neither moving

Covering the syllabus phrase: deadlock

Two cooks. One knife, one chopping board. Each needs both to work.

Cook A holds the knife Cook B holds the board knife board has has A waits for the board B waits for the knife neither will let go before getting the other — both wait forever
A CIRCLE OF WAITING · NOBODY IS BLOCKED BY A BUG, YET NOTHING MOVES
src / kitchen / Stuck.java  — this program never ends
1package kitchen;
2
3public class Stuck
4{
5 static String knife = "knife";
6 static String board = "board";
7
8 public static void main(String[] args)
9 {
10 Thread a = new Thread()
11 {
12 public void run()
13 {
14 synchronized (knife)
15 {
16 System.out.println("A has the knife");
17 synchronized (board)
18 {
19 System.out.println("A chopped");
20 }
21 }
22 }
23 };
24
25 Thread b = new Thread()
26 {
27 public void run()
28 {
29 synchronized (board) // opposite order
30 {
31 System.out.println("B has the board");
32 synchronized (knife)
33 {
34 System.out.println("B chopped");
35 }
36 }
37 }
38 };
39
40 a.start();
41 b.start();
42 }
43}
Console
running
kitchen.Stuck [Java Application] — still running
A has the knifeB has the board (nothing more — press the red stop button)

Read the output carefully. This is the signature of a deadlock:

Two lines printed, then silence. Both threads got their first lock and stopped at the second.
No exception, no error, no crash. Nothing is wrong with any single line. Eclipse simply never says terminated.
Line 14 takes knife then board. Line 29 takes board then knife. That opposite order is the entire cause.
CHUNK 4 OF 6 0:26 – 0:32

The fix — everyone picks up in the same order

LOCK ORDERING
Decide one order for the locks — knife first, then board — and make every thread follow it. A circle of waiting cannot form if nobody ever reaches backwards.
src / kitchen / Unstuck.java  — read only, thread B's two lines swapped
29 synchronized (knife) // same order as A
30 {
31 System.out.println("B has the knife");
32 synchronized (board)
33 {
34 System.out.println("B chopped");
35 }
36 }
Console
terminated
<terminated> kitchen.Unstuck [Java Application]
A has the knifeA choppedB has the knifeB chopped

Two words swapped, and the program finishes. Whoever gets the knife first now holds it until done, and the other waits its turn rather than holding something hostage.

Nothing was added. No timeout, no clever library, no extra thread. The same locks, taken in the same order by everyone.
It scales. Ten threads and five locks are safe if all ten follow one agreed order.
Order who, not when. A may finish before B or after — still unpredictable, still fine. What is fixed is that neither can be stranded.
If asked how to prevent deadlock, lock ordering is the answer to give. It is the one technique that needs no extra machinery and is easy to state: agree an order for the locks, and make every thread take them in it.
CHUNK 5 OF 6 0:32 – 0:36

The four mistakes, across the whole topic

Everything that goes wrong with threads in this unit is one of these four. Each has a symptom you can recognise without a debugger.

run() instead of start() Symptom: the output is suspiciously tidy, always in the same order.
Why: no thread was created; it ran as an ordinary method call.
Check: print Thread.currentThread().getName() — if it says main, there is your answer. Module 11.
no synchronized Symptom: correct almost always, wrong once in hundreds of runs.
Why: two threads got between a check and the action after it.
Check: find shared data that more than one thread changes. Module 12.
locks in different orders Symptom: the program prints a little, then hangs. No error at all.
Why: each thread holds what the other is waiting for.
Check: look for two nested synchronized blocks in opposite orders. This module.
wait() inside an if Symptom: fine with two threads, occasionally wrong with more.
Why: the condition changed again between the notify and the wake-up.
Check: every wait() should sit inside a while. This module.
Race condition
Deadlock
What happens
Threads both act, data ends up wrong
Threads both stop, nothing happens
Symptom
Wrong answer, rarely
Program hangs, no error
Cause
Too little locking
Too much locking, badly ordered
Fix
Add synchronized
Take locks in one agreed order
Our example
Two people booking seat A4
Two cooks, one knife, one board
In our code
Booking.java — the double booking
Stuck.java — the knife and the board

The pairing worth remembering: the fix for one is the cause of the other. Lock too little and data breaks; lock too much, carelessly, and everything stops. Threads are the art of locking exactly enough.

CHUNK 6 OF 6 0:36 – 0:40

Teach-back — closing Multithreaded Programming

Say each answer aloud before opening it. If you can name the symptom, you can diagnose any threading question in the hall.

1. A program prints two lines then stops responding, with no error. What is wrong, and what is the fix?
2. A counter should reach 2000 and prints 1997. Which of the four mistakes is it?
3. Explain a race condition and a deadlock to a classmate in one sentence each, using our two examples.

Show worked solution
1. Deadlock. Two threads each hold a lock the other needs. The giveaway is no error — a crash would name a line; a hang names nothing. Fix by taking the locks in one agreed order everywhere.

2. A missing synchronized. Not deadlock — the program finished. count = count + 1 is read, add, write; two threads read the same value and one increment is lost. Three lost here.

3. A race condition is two people booking seat A4 at once because both checked before either booked — the data ends up wrong. A deadlock is two cooks each holding one tool and waiting for the other's — nothing ends up wrong, because nothing ends up happening at all.

Multithreaded Programming is complete. All eight syllabus sub-topics and three previous-year questions are covered. Module 14 recaps the whole unit.

Practice

Three problems

Attempt each before opening the solution.
1 This method throws IllegalMonitorStateException the moment it runs. Why, and what is the one-word fix?
1void take() throws Exception 2{ 3 while (ready == false) 4 { 5 wait(); 6 } 7}
Show solution
The method is not synchronized. wait() releases the lock the thread is holding — but this thread never took one, so there is nothing to release.

The fix:
1synchronized void take() throws Exception
Worth noticing: it compiles perfectly. Nothing in the syntax is wrong — the rule is about what is true at run time, which is why this is an exception and not a compiler error.
2 Two threads transfer money between accounts A and B. One transfers A→B, the other B→A, and each locks the source account then the destination. What happens, and how would you fix it without removing either lock?
Show solution
Deadlock, eventually. The first thread locks A then wants B; the second locks B then wants A. It is the knife and board with money.

The fix is lock ordering, and the trick is choosing an order that does not depend on direction. Lock by account number, always lowest first:
1if (first.number < second.number) 2{ 3 synchronized (first) { synchronized (second) { transfer(); } } 4} 5else 6{ 7 synchronized (second) { synchronized (first) { transfer(); } } 8}
Both directions now take the lower-numbered account first, so no circle can form. Both locks are kept — only the order changed.
3 Your program hangs. How do you tell a deadlock apart from a thread that is simply doing slow work?
Show solution
Slow work makes progress; a deadlock makes none. Three practical checks:

Print as you go. Add a line inside the loop that is running. Slow work keeps printing; a deadlock printed its last line and stopped.

Wait longer. Slow work finishes eventually. A deadlock will still be there tomorrow.

Look for nested locks. A deadlock needs at least two, taken in different orders by different threads. One lock alone cannot deadlock this way.

And the giveaway in Eclipse: the red stop button stays enabled and the console never prints <terminated>, no matter how long you leave it.

Project so far

Unit2Project — complete
  • m2–m7 school · travel · campus · safety · college
  • m8–m10 marks · insure · bank · admit
  • m11–m12 kitchen · cinema
  • kitchen — new this module
    • new Counter.java
    • new Canteen.java
    • new Stuck.java
    • new Unstuck.java

Every syllabus topic in Unit 2 is now covered. Module 14 recaps the unit; Module 15 is a timed self-test.

UP NEXT · MODULE 14
Unit Recap
Modules 14–15 arrive in this same file
press ↓ again, or click
Module 14 · Unit Recap
0%
15 min
next   back   chunk
MODULE 14 · UNIT RECAP · 15 MIN
CHUNK 1 OF 2 0:00 – 0:10

The whole unit, one card per topic

WHERE THE MARKS ARE Classes & Interfaces 8 questions Exception Handling 6 Multithreading 4 18 past questions every one worked in full with a runnable program classes carry the most — revise there first
Three areas · eighteen questions · unequal weight
All nineteen syllabus items, across the seven topics of Classes and Interfaces, Exception Handling and Multithreaded Programming
Nothing new is taught here. Definition and syntax only — this is the page to read the night before.
1 Singleton class Module 2
A class built so only one object of it can ever exist, reached through one shared method. One slot · locked door · one official way in.
src / recap / OneMonitor.java
1package recap;
2
3public class OneMonitor
4{
5 private static OneMonitor only;
6
7 private OneMonitor() { }
8
9 public static OneMonitor getInstance()
10 {
11 if (only == null)
12 {
13 only = new OneMonitor();
14 }
15 return only;
16 }
17
18 public static void main(String[] args)
19 {
20 OneMonitor a = getInstance();
21 OneMonitor b = getInstance();
22 System.out.println("Same object ? " + (a == b));
23 }
24}
Console
terminated
<terminated> recap.OneMonitor [Java Application]
Same object ? true
All three pieces are needed together. synchronized is what keeps it single when threads call at once.
2 Abstract class Module 3
A class with at least one method left unwritten. No object of it can be made; every subclass must supply the missing method.
src / recap / ShapeDemo.java
1package recap;
2
3abstract class Shape
4{
5 abstract void draw();
6}
7
8class Circle extends Shape
9{
10 void draw()
11 {
12 System.out.println("Drawing a circle");
13 }
14}
15
16public class ShapeDemo
17{
18 public static void main(String[] args)
19 {
20 Shape s = new Circle(); // abstract type, real object
21 s.draw();
22 }
23}
Console
terminated
<terminated> recap.ShapeDemo [Java Application]
Drawing a circle
It can have a constructor, and it runs when a subclass object is built. new Reservation() is a compile error.
3 Nested & inner classes Module 4
A class written inside another, because outside it the class would mean nothing.
src / recap / College.java
1package recap;
2
3public class College
4{
5 static class Address
6 {
7 void show()
8 {
9 System.out.println("Ibrahimbagh, Hyderabad");
10 }
11 }
12
13 class Principal
14 {
15 void show()
16 {
17 System.out.println("Principal of Vasavi");
18 }
19 }
20
21 public static void main(String[] args)
22 {
23 new College.Address().show();
24 College c = new College();
25 c.new Principal().show();
26 }
27}
Console
terminated
<terminated> recap.College [Java Application]
Ibrahimbagh, HyderabadPrincipal of Vasavi
Creating an inner one: c.new Principal() — read it as "ask c to make me a Principal".
4 Interface Module 5
A list of method names with no bodies — a promise about what will exist, never about how it works.
src / recap / VasaviLibrary.java
1package recap;
2
3interface Library
4{
5 void drawBook();
6 void returnBook();
7 void checkStatus();
8}
9
10public class VasaviLibrary implements Library
11{
12 public void drawBook() { System.out.println("Book issued"); }
13 public void returnBook() { System.out.println("Book returned"); }
14 public void checkStatus() { System.out.println("2 books out"); }
15
16 public static void main(String[] args)
17 {
18 Library l = new VasaviLibrary();
19 l.drawBook();
20 l.checkStatus();
21 }
22}
Console
terminated
<terminated> recap.VasaviLibrary [Java Application]
Book issued2 books out
One parent, many interfaces. That single rule decides interface versus abstract class every time.
5 Package & access control Modules 6–7
A package is a folder. The package line must match the folder path exactly.
Level
Same package
Subclass elsewhere
Anywhere
private
no
no
no
default
yes
no
no
protected
yes
yes
no
public
yes
yes
yes
src / recap / StudentId.java
1package recap;
2
3public class StudentId
4{
5 private String roll; // nobody may touch it directly
6
7 public void setRoll(String value)
8 {
9 if (value.length() == 10)
10 {
11 roll = value;
12 }
13 else
14 {
15 System.out.println("Rejected : " + value);
16 }
17 }
18
19 public static void main(String[] args)
20 {
21 StudentId s = new StudentId();
22 s.setRoll("160122733"); // 9 digits
23 s.setRoll("1601227330"); // 10 digits
24 System.out.println("Stored : " + s.roll);
25 }
26}
Console
terminated
<terminated> recap.StudentId [Java Application]
Rejected : 160122733Stored : 1601227330
Encapsulation = private data + a public method that checks. final = cannot change. A top-level class may only be public or default.
6 Exception handling Modules 8–10
An exception is an object Java creates when something goes wrong at run time. Uncaught, the program stops.
src / recap / Marks.java
1package recap;
2
3class TooLowException extends Exception
4{
5 TooLowException(String m)
6 {
7 super(m);
8 }
9}
10
11public class Marks
12{
13 public static void main(String[] args)
14 {
15 try
16 {
17 int m = 8;
18 if (m < 35)
19 {
20 throw new TooLowException(m + " is a fail");
21 }
22 }
23 catch (TooLowException e)
24 {
25 System.out.println("Caught : " + e.getMessage());
26 }
27 finally
28 {
29 System.out.println("-- done --");
30 }
31 }
32}
Console
terminated
<terminated> recap.Marks [Java Application]
Caught : 8 is a fail-- done --
throw is the action, inside the body. throws is the label, on the signature. Checked = the compiler insists; unchecked = it stays quiet.
7 Multithreaded programming Modules 11–13
A thread is a second line of execution inside one program, sharing that program's memory. A process is the program itself, with memory of its own.
src / recap / Seat.java
1package recap;
2
3public class Seat extends Thread
4{
5 static boolean taken = false;
6
7 static synchronized void book(String who)
8 {
9 if (taken == false)
10 {
11 taken = true;
12 System.out.println(who + " booked it");
13 }
14 else
15 {
16 System.out.println(who + " : too late");
17 }
18 }
19
20 public void run()
21 {
22 book(Thread.currentThread().getName());
23 }
24
25 public static void main(String[] args)
26 {
27 new Seat().start();
28 new Seat().start();
29 }
30}
Console
terminated
<terminated> recap.Seat [Java Application]
Thread-0 booked itThread-1 : too late
Lifecycle: New → Runnable → Running → Blocked/Waiting → Terminated. Runnable and Running swap many times; Terminated is final.
Race = too little locking, data ends up wrong. Deadlock = too much, badly ordered, nothing happens. Fix with synchronized and one agreed lock order.
CHUNK 2 OF 2 0:10 – 0:15

Everything you built, and how to keep it

Thirteen modules produced one Eclipse project with nine packages. This is the whole of it in one place.

Unit2Project the one Eclipse project └── src every package lives under here ├── school Singleton │ ├── ClassMonitor.java m2 │ ├── MonitorDemo.java m2 │ └── SafeMonitor.java m12 ├── travel Abstract classes │ ├── Reservation.java m3 │ ├── ReserveTrain.java m3 │ └── ReserveBus.java m3 ├── campus Nested classes │ ├── College.java m4 │ ├── InnerDemo.java m4 │ └── AnonDemo.java m4 ├── safety Interfaces │ ├── FireSafety.java m5 │ ├── School.java m5 │ └── LibraryDemo.java m5 ├── college Packages ├── college.exams │ ├── Paper.java m7 │ └── PracticalPaper.java m7 ├── college.office │ ├── Clerk.java m7 │ └── PaperDemo.java m6 ├── marks Exceptions │ ├── Average.java m8 │ ├── FinallyDemo.java m8 │ ├── ResultCard.java m8 │ ├── InvalidMarkException.java m9 │ ├── MarkEntry.java m9 │ ├── Register.java m9 │ ├── RootOfAll.java m9 │ ├── Office.java m10 │ └── ThreeKinds.java m10 ├── insure Exceptions │ ├── Policy.java m10 │ └── Insurance.java m10 ├── bank Exceptions │ ├── InsufficientFundsException.java m10 │ ├── BankAccount.java m10 │ └── Branch.java m10 ├── admit Exceptions │ ├── InvalidAgeException.java m10 │ └── AgeCheck.java m10 ├── kitchen Threads │ ├── Cook.java m11 │ ├── Washer.java m11 │ ├── TwoCooks.java m11 │ ├── OneProcess.java m11 │ ├── Paced.java m12 │ ├── Counter.java m13 │ ├── Canteen.java m13 │ ├── Stuck.java m13 │ └── Unstuck.java m13 ├── cinema Threads │ ├── Booking.java m12 │ ├── SafeBooking.java m12 │ └── WhySync.java m12 └── recap Revision ├── OneMonitor.java m14 ├── ShapeDemo.java m14 ├── VasaviLibrary.java m14 ├── StudentId.java m14 ├── Marks.java m14 └── Seat.java m14

Making a file, saving it, running it

The same four moves produced every file above. Worth having them in one place.

1New package: right-click srcNew → Package. Type the full dotted name — college.exams, not one level at a time.
2New class: right-click the package → New → Class. Tick public static void main(String[] args) for anything you intend to run. Leave it unticked for an exception class or shared data.
3Save: Ctrl + S. Eclipse compiles on every save, so red marks appear as you type — before you ever press Run.
4Run: the green button, or Ctrl + F11. Output appears in the Console view at the bottom.
Keeping the project. Right-click Unit2ProjectExport → General → Archive File gives you a single zip of everything. Import it on any machine with File → Import → Existing Projects into Workspace. Worth doing before the exam — a lab machine being reimaged is not a good day to discover this.

Doing it without Eclipse

Module 6's manual route, in case you are ever on a machine without an IDE.

COMMANDjavac -d . college\exams\Paper.javajava college.exams.Paper

javac takes a file path with backslashes and .java. java takes a class name with dots and no extension. Run both from the folder above the package.

All nineteen syllabus items are covered, across seven topics and thirty-eight files. Module 15 is a timed test over the whole unit, with every previous-year question worked in full.
That is the unit, end to end. Fifteen modules, one Eclipse project, eighteen past questions answered. One module left, and it is the one where you find out what stuck.
UP NEXT · MODULE 15
Timed Self-Assessment
The last module in this file
press ↓ again, or click
Module 15 · Timed Self-Assessment
0%
15 min
next   back   chunk
MODULE 15 · TIMED SELF-ASSESSMENT · 15 MIN
CHUNK 1 OF 2 0:00 – 0:08

Eight minutes, seven topics

One question from each topic of Classes and Interfaces, Exception Handling and Multithreaded Programming
Work through all seven before opening anything. Write your answers down — reading a solution and thinking "yes, I knew that" is not the same as having known it.
7questions
8minutes
~1minute each

The test

Solutions are in the next chunk, with the full PYQ answer key.
1 Singleton. This compiles and runs. Why does it fail to be a Singleton, and what one word fixes it?
1class Registrar 2{ 3 private static Registrar only; 4 5 Registrar() { } 6 7 public static Registrar getInstance() 8 { 9 if (only == null) { only = new Registrar(); } 10 return only; 11 } 12}
2 Abstract classes. Two of these four lines will not compile. Which two, and what does Eclipse say?
1abstract class Shape { abstract void draw(); } 2class Circle extends Shape { } 3Shape s = new Shape(); 4Shape t = new Circle();
3 Interfaces. A class already extends Employee. It must also be printable and saveable. Can it be? Explain in one sentence, and write the class header.
4 Packages and access. Paper is in college.exams with a protected int marks. Which of these can read it? (a) another class in college.exams (b) a subclass in college.office (c) an unrelated class in college.office
5 Exception handling. What does this print, exactly?
src / test / Trace.java  — type it, predict, then run it
1package test;
2
3public class Trace
4{
5 public static void main(String[] args)
6 {
7 System.out.println("A");
8 try
9 {
10 int[] n = new int[2];
11 n[3] = 10;
12 System.out.println("B");
13 }
14 catch (ArithmeticException e)
15 {
16 System.out.println("C");
17 }
18 catch (Exception e)
19 {
20 System.out.println("D");
21 }
22 finally
23 {
24 System.out.println("E");
25 }
26 }
27}
6 Custom exceptions. Fill both blanks, and say why each word is the one it is.
1static void check(int n) ______ TooLowException 2{ 3 if (n < 10) { ______ new TooLowException("too low"); } 4}
7 Multithreading. A program prints three lines and then hangs with no error message. Name the fault, and give the one technique that prevents it.
How to read your score. Five or more means the unit has landed. Three or four means one topic needs another pass — the solutions say which. Below three, work back through the module that question came from rather than re-reading this page.
CHUNK 2 OF 2 0:08 – 0:15

Solutions

1Singleton — why it is not one
Show solution
Line 5: the constructor is not private. Anyone can still write new Registrar() and get a second one, so the slot and the method achieve nothing.

The fix: private Registrar() { }. All three pieces are needed together — one slot, a locked door, one official way in.

Half a mark more: getInstance() should also be synchronized, or two threads calling at once can both pass line 9. Modules 2 and 12.
2Abstract classes — which two fail
Show solution
Line 2 and line 3.

Line 2: "The type Circle must implement the inherited abstract method Shape.draw()" — a subclass must either write the method or be declared abstract itself.

Line 3: "Cannot instantiate the type Shape" — no object of an abstract class can be created directly.

Line 4 is fine, and is the point of the whole pattern: an abstract type holding a concrete object. Module 3.
3Interfaces — one parent, many interfaces
Show solution
Yes. A class may extend only one class but implement any number of interfaces, so the single parent is spent on Employee and the two capabilities cost nothing.
1class Manager extends Employee implements Printable, Saveable
extends comes first, then implements, interfaces comma-separated. Module 5.
4Access — who can read protected
Show solution
(a) and (b). Not (c).

(a) same package — protected includes everything default allows.
(b) a subclass in another package — this is the one door protected opens that default does not.
(c) unrelated class in another package — refused. Inheritance is what earns the access, not the package name looking similar. Module 7.
5Exception handling — trace the output
Show solution
A D E

src / test / Trace.java  — what it actually prints
1public static void main(String[] args)
2{
3 System.out.println("A"); // prints
4 n[3] = 10; // throws here
5 System.out.println("B"); // never reached
6 catch (ArithmeticException e) ... // no match, skipped
7 catch (Exception e) ... // matches, prints D
8 finally ... // always, prints E
9}
Console
terminated
<terminated> test.Trace [Java Application]
ADE
Line 5 throws ArrayIndexOutOfBoundsException, so B never prints — the rest of the try is abandoned.

The first catch wants ArithmeticException, which does not match, so C is skipped. The second catches Exception, which every exception falls under, so D prints.

E always prints. That is the whole job of finally. Module 8.
6Custom exceptions — throw or throws
Show solution
Line 1 takes throws. It is a label on the method signature, warning callers this may fail that way.

Line 3 takes throw. It is the action, happening now, inside the body.

The giveaway is new: only throw is ever followed by an object. throws is followed by a type. Module 9.
7Multithreading — prints, then hangs
Show solution
Deadlock. Two threads each hold a lock the other is waiting for, so neither can move.

The giveaway is the absence of an error. A crash names a line; a race gives a wrong answer and finishes. Only a deadlock stops silently with the console never saying <terminated>.

The technique: consistent lock ordering. Agree one order for the locks and make every thread take them in it — a circle of waiting cannot form if nobody reaches backwards. Module 13.

The three areas, and what each was worth

WHERE YOUR SEVEN QUESTIONS CAME FROM Classes & Interfaces questions 1 to 4 Exception Handling questions 5 and 6 Multithreading question 7 the split matches the papers: half the marks sit in classes and interfaces if you lost marks in one box, that is the module to reopen
Seven questions · three areas · weighted the way the paper is

How to read your score

If you lost marks on
The thing to reread
Where
an interface question
a class is a thing; an interface is a promise about what a thing can do
Module 5
checked against unchecked
the tree starts at Throwable and splits into Error and Exception
Module 9
a custom exception
extends Exception, and super(message) because the language requires it
Module 9
thread output order
there is no order — that is the entire point, and the reason for join()
Modules 11 and 12
anything synchronized
one thread at a time through that block, everyone else waits
Module 12
In our code
every row above has a runnable program behind it
press the badge

Your finished project

Unit2Project the one Eclipse project └── src every package lives under here ├── classes the class and interface programs ├── exceptions try, catch, finally, custom throwables ├── threads Thread, Runnable, join, synchronized └── selftest your seven answers
Every folder above holds programs you typed and ran yourself. If one is empty, that is the area to go back to — not because the marks demand it, but because a program you have never run is a program you do not yet trust.

The eighteen exam questions, in one place

Every previous-year question landed in this unit, with the shape of a full-mark answer and where the worked version lives.

Classes and Interfaces — eight questions
2m
"Define a singleton class. Give an example."
Definition, then the three pieces: private static field, private constructor, public static getInstance(). Show the same object returned twice with a == b printing true.
M2
4m
"Design an abstract class Reservation containing an abstract method reserve(). Implement this class through two subclasses, ReserveTrain and ReserveBus."
Abstract parent with abstract void reserve() plus one shared concrete method. Two subclasses each writing reserve(). A driver holding both in Reservation variables, with output.
M3
4m
"Design an interface Library with methods drawBook(), returnBook(), and checkStatus(). Implement this interface through a class VasaviLibrary."
Interface with three bodyless methods; one class implementing all three. Miss one and it will not compile — worth saying so in the answer.
M5
4m
"Discuss the access specifiers in Java in detail."
Purpose first, then all four, then the visibility table. Add that default is a real choice not an omission, and that a top-level class may only be public or default.
M7
4m
"Under what circumstances would you declare a member or class as final or protected? Justify your answer."
Two halves: final when a value or behaviour must not vary; protected when subclasses need access but the wider program must not. Both narrow what the rest of the program can do.
M7
4m
"Explain the benefit of declaring a class as protected and final, and the risk if these are not applied."
Benefit/risk table. Note that a top-level class cannot be protected — only its members can. That boundary is what the question is testing.
M7
2m
"What is required to declare a class as immutable?"
All fields private final, set in the constructor; no setters; class final. Name String as the example.
M7
4m
"Explain the key principles of object-oriented programming."
Four pillars, one line and one example each: Abstraction, Encapsulation, Inheritance, Polymorphism. Every example can come from this unit.
M7
Exception handling — six questions
2m
"Differentiate between checked and unchecked exceptions, with examples."
Checked = the compiler insists; unchecked = it stays silent. One named example each — IOException and ArithmeticException. Unnamed examples score nothing.
M9
2m
"Explain the use of multiple catch blocks for a single try block, with an example."
Java checks top to bottom and runs the first match only. Order specific before general, or the later blocks are unreachable — a compile error.
M10
4m
"Design a four-class hierarchy in an insurance context that incorporates custom exceptions."
Custom exception, abstract parent, two children. The parent's method works for both because the minimum is abstract. Show one issued and one rejected.
M10
4m
"Write a program using an array of BankAccount objects that demonstrates five named exceptions, handled using multiple catch blocks, throws, and finally."
Know which line causes which of the five. Write all five catch blocks, then show two runs with one variable changed — only the first failure in a try ever fires.
M10
4m
"Write a program that throws a custom InvalidAgeException when a negative age is entered, and re-prompts in a loop until valid."
The try sits inside the loop. The flag turns true only after the check passes. Show two rejections then an acceptance — one rejection does not prove it loops.
M10
4m
"Write a program that catches ArithmeticException, ArrayIndexOutOfBoundsException and any user-defined exception."
Drive all three from one variable and show three runs. Beats writing three separate programs, and finally prints on every one.
M10
Multithreaded programming — four questions
2m
"Differentiate between Thread and Process."
Lead with memory: a process has its own, threads share their process's. Add one more row — switching cost, or what happens when one crashes.
M11
4m
"With a suitable example, explain how to create threads using the Thread class."
Class extends Thread, override run(), create an object, call start() — never run(). Show the output and note the order may vary.
M11
4m
"Briefly explain the life cycle of a thread."
Draw the five states with each arrow labelled by its event. Say Runnable and Running alternate many times, and that Terminated is final.
M11
2m
"Explain the significance of thread synchronization in Java."
Problem, mechanism, example: threads share memory so two can corrupt it; synchronized admits one at a time; two users booking one seat.
M12
Unit 2 complete

That is the whole unit.

You started with an empty Eclipse workspace. You now have a project of forty-four files covering every syllabus item, and you have seen each of the eighteen exam questions answered with a program that actually runs. Nothing here was described to you without being shown.

19/19
syllabus covered
18/18
PYQs answered
15
modules
14
packages built

Every module stays open. The three worth returning to before an exam are Module 14 for the one-card-per-topic revision, Module 10 for the exception programs, and Module 13 for the race-versus-deadlock distinction that separates a good answer from a full one.

Glossary
every term used in Unit 2

Terms are listed in the order you meet them. Each says where it is taught, so you can jump back to the module if the one-line version isn't enough.

From Unit 1, used throughout
classA blueprint describing what its objects will hold and be able to do.Unit 1
objectOne thing built from a class, with its own copy of the data. Made with new.Unit 1
constructorThe method that runs once when an object is created, to set it up. Same name as the class, no return type.Unit 1
overrideA subclass writing its own version of a method the parent already had. The subclass's version is the one that runs.Unit 1
referenceA name that points at an object. Two references can point at the same object — that is what == tests.Unit 1
driverA small class whose only job is to hold main and run the classes you actually want to demonstrate.Unit 1
Module 2 — Singleton
SingletonA class built so that only one object of it can ever exist, reached through one shared access method.Module 2
encapsulationKeeping a class's inner workings hidden and exposing only a controlled way to use it. The outside gets a door, not a key.Module 2
staticBelonging to the class itself rather than to any one object. A static field exists once, shared by everything.Module 2
lazy / eagerLazy: the object is built on the first request. Eager: it is built as soon as the class loads.Module 2
Module 3 — Abstract Classes
abstract methodA method declared with no body at all, ending in a semicolon. Every subclass must supply its own version.Module 3
abstract classA class holding at least one abstract method. No object of it can be created directly.Module 3
concrete methodAn ordinary, fully written method. Subclasses inherit it as-is unless they choose to override it.Module 3
instantiateTo make an object of a class. "Cannot instantiate" means Java refuses to build one.Module 3
compile-time / run timeCompile-time errors appear as you type or save, before the program runs. Run-time errors appear only once it is running.Module 3
Module 4 — Nested & Inner Classes
nested classA class written inside another class's braces. Its full name includes the outer class.Module 4
static nested classA nested class marked static. Needs no outer object, and cannot read the outer object's fields.Module 4
inner classA nested class without static. Tied to one particular outer object, and can read its private data.Module 4
anonymous inner classA class written and used in a single expression, never given a name. Ends with };.Module 4
Module 5 — Interfaces
interfaceA list of method names with no bodies — a promise about what will exist, never about how it works.Module 5
implementsThe keyword a class uses to sign an interface. It must then supply every method the interface named.Module 5
default methodAn interface method that does have a body. Signers inherit it free and may override it.Module 5
static method (interface)A helper belonging to the interface itself, called as InterfaceName.method(), never inherited.Module 5
Modules 6–7 — Packages & Access
packageA folder holding related classes. The package line in a file must match the folder it sits in.Module 6
importA line saying which other package a class name comes from, so you can use the short name.Module 6
fully qualified nameA class's real name including its package — college.exams.Paper, not just Paper.Module 6
bytecodeWhat javac produces — the .class file. Not readable by you, and not machine code either; it is what Java runs.Module 6
access specifierThe word deciding who may use a member: private, default, protected, or public.Module 7
default accessNo access word at all. Visible inside the same package only — a real choice, not an omission.Module 7
protectedSame package, plus subclasses in any package. The only level whose answer depends on inheritance.Module 7
Tooling words
javacThe Java compiler. Turns .java source into .class bytecode.Module 6
method stubAn empty method Eclipse writes for you, ready to be filled in — such as the main tickbox in the New Class wizard.Module 2
refactorChanging code's structure without changing what it does. Eclipse's Refactor menu moves and renames things safely.Module 7
Presenter> next< back pick link, then > to open full screen