Unit 2 home
LAB 4 · EXCEPTION HANDLING
2:00:00
LAB 4 · P 1/10PGDN NEXT POINT · PGUP BACK

UI24PC321CS · OOP THROUGH JAVA LAB · B.E. III SEM · VASAVI COLLEGE OF ENGINEERING

Lab 4 — the program
that refuses.

An admissions desk that will not accept a negative age, and a bank counter that refuses a withdrawal without leaving the account half-emptied. Two custom exceptions you design yourself, one multi-catch, and a finally that runs whether the day went well or badly.

R-24 SYLLABUS · LAB PROGRAMMING EXERCISE 4 · VERBATIM

“A program to demonstrate Exception Handling.”

TOOLEclipse IDESame workspace as Lab 3
GRADED WORK2 exercises100 marks total
WARM-UP5 theory + 4 drillsNot graded · do them first
YOU ALREADY KNOWAll of itClasses 17–20

PART 1 · OPENER · l04-opener

Last lab your program lied.
Today you teach it to refuse.

Hand Lab 3's AttendanceCalculator a total of zero classes. It divides by zero, gets NaN, and prints a percentage with complete confidence. Nothing crashes. The report is simply false.

ATTENDANCE REPORT · RUNNING

AttendanceReport — Lab03
STUDENTATTHELDPERCENTVERDICT
Diya Sharma4250
Rohit Verma3750
Kavya Rao00
Meera Iyer3850
waiting…

Open your Lab03 project and run it before reading on. Seeing it once is worth more than being told.

Four things you will be able to do

Catch a failure

Wrap the one risky line, name the exception, let the program carry on.

Design your own

InvalidAgeException extends Exception — your class, your message, your rule.

Handle several at once

Separate catch blocks in the right order, and the | multi-catch form.

Guarantee cleanup

finally — runs on the success path and on every failure path.

The one picture that decides everything

THE HIERARCHY — AND THE BAND THAT DECIDES WHO THE COMPILER CHASES

UNCHECKED BAND CHECKED BAND Throwable the root — everything Java can throw Error Exception IOException InvalidAgeException catch it or declare throws — no choice RuntimeException handle it if you like — nobody insists OutOfMemoryError StackOverflowError the JVM in trouble — do not catch Error is unchecked too — the compiler ignores it just as it ignores RuntimeException. You leave Error alone for a different reason: there is nothing sensible your code can do about it.

THE DEFINITION AN EXAMINER ACCEPTS

“An exception is checked if the compiler forces every caller to deal with it — either catch it, or declare throws and pass the duty on. It is unchecked if the compiler says nothing.”

Add the mechanism: “the split is decided purely by position in the hierarchy — anything below RuntimeException or Error is unchecked, everything else below Exception is checked.”

What you are building, in one picture

eclipse-workspace — Lab04 — Eclipse IDE
FileEditSourceRefactorNavigateSearchProjectRunWindowHelp

PACKAGE EXPLORER · HIERARCHICAL

Lab04
src
com
college
admission
InvalidAgeException.java
Student.java
bank
BankAccount.java
InsufficientFundsException.java
app
AdmissionDesk.java
BankDriver.java
JRE System Library [JavaSE-21]
Student.java AdmissionDesk.java
1package com.college.admission;
2
3public class Student
4{
5 // setAge refuses a negative age by
6 // throwing, not by returning -1
7}
CONSOLE · AdmissionDesk [Java Application]
Enter age:
 
— you fill this in at Part 6 —
THREE PACKAGES, SIX FILES · admission AND bank HOLD THE RULES · app HOLDS THE TWO PROGRAMS THAT RUN THEM

Two hours, ten parts

#PARTMINBY
1Opener20:02
2Prelab theory — five questions, in ink110:13
3Model answers — mark your own60:19
4Four drills — five files280:47
5Walkthrough and project setup90:56
6Exercise 1 — 45 marks181:14
7Exercise 1 solution81:22
8Exercise 2 — 45 marks211:43
9Exercise 2 solution81:51
10Debrief, rubric and viva92:00

WHERE THIS LAB SITS

LAB 4 OF 14 · 10 PARTS · 4 UNGRADED DRILLS + 2 GRADED EXERCISES · 100 MARKS · THREE PACKAGES, SIX FILES

Start the clock in the header now. It runs once for the whole session. Theory home: Classes 17–20.

PART 2 · PRELAB THEORY · l04-prelab-theory · 11 MIN

Five questions. Pen, notebook,
before Eclipse opens.

These five are your viva. Real sentences, not keywords — and if one defeats you, write down what you do not know about it.

Q1

What decides whether an exception is checked or unchecked?

  • Name the class on the dividing line.
  • What does the compiler force you to do for a checked one that it does not for an unchecked one?
write yours first
A1
  • The dividing line is RuntimeException.
  • Anything extending RuntimeException or Error is unchecked. Everything else under Exception is checked.
  • Checked: the compiler refuses to build unless every caller catches it or declares throws.
  • Unchecked: the compiler says nothing at all.
  • So extends Exception decides whether the next programmer is allowed to ignore this.
Q2

Why must catch (Exception e) come last?

  • What does the compiler say if you put it first?
  • Why does the rule exist — how does Java pick which block runs?
write yours first
A2
  • Java runs the first block whose type can hold the thrown object.
  • Exception holds anything, so first place means nothing after it can ever run.
  • Unreachable code is an error, not a warning — the file will not build at all.
  • Eclipse names both blocks: Unreachable catch block for ArithmeticException.
  • Rule: most specific first, most general last. Unrelated types can go in any order.
Q3

What exactly does finally guarantee?

  • Does it run when try succeeds?
  • When a catch handles a throw?
  • When nothing matches the throw?
  • Name one job that belongs inside it.
write yours first
A3
  • It runs in all three cases — and also if try hits a return.
  • When nothing matches, it runs on the way out, just before the program stops.
  • The job is closing a resource: a Scanner, a file, a held seat.
  • sc.close() at the end of try looks identical on a good day and is a bug on a bad one — if the line above throws, the close is skipped.
Q4

When is your own exception better than a built-in one?

  • IllegalArgumentException would work for a negative age — give two reasons to write InvalidAgeException anyway.
  • Give one case where writing your own is over-engineering.
write yours first
A4
  • The name is documentationInvalidAgeException in a trace names the rule that broke.
  • It can be caught on its own, so a caller answers “bad age” differently from “bad something else”.
  • Over-engineering: do not invent one for a condition that is not exceptional.
  • A search finding nothing is an ordinary result — return an empty list, do not throw.
Q5 · PREDICT THE OUTPUT

Exactly what does this print, and in what order?

Copy into your notebook — do not run it
1int[] n = { 10, 20 };
2try { System.out.println(n[1] / 0); }
3catch (ArrayIndexOutOfBoundsException e) { System.out.println("A"); }
4catch (ArithmeticException e) { System.out.println("B"); }
5finally { System.out.println("C"); }
6System.out.println("D");
  • Write the output in your notebook before you reveal the answer.
  • Then the part that carries the mark: change one character so the answer becomes A, C, D. Which character?
write yours first
A5
CONSOLE
B
C
D
  • n[1] is valid — indexes 0 and 1 both exist, so block A never runs. This is the half everybody misreads: the array makes people expect an index problem.
  • 20 / 0 throws ArithmeticException, so B prints.
  • finally always runs → C. The exception was handled, so the program continues → D.
  • The one character: make the index 2. Out of bounds, so the answer becomes A, C, D.
  • Notice what that proves — the division never happened. When a line throws, nothing later on that line runs.
Do not reveal a single answer until all five are written. Each answer unlocks under its own question — the point is finding out which of the five you only thought you knew.

PART 3 · SELF-MARK CHECKPOINT · l04-prelab-theory-answers · 6 MIN

One picture that settles
answers 3 and 5.

You revealed each answer under its own question. Now check the two that trip everybody: where control actually goes when a line throws, and what finally guarantees.

THE TWO ANSWERS WORTH SEEING AS A PICTURE

THE THREE ROUTES OUT OF A try BLOCK — ALL OF THEM PASS THROUGH finally

finally { every route arrives here no exceptions try { the risky line 1 · no throw rest of try runs catch is skipped 2 · throws, a catch matches catch { rest of try skipped 3 · throws, nothing matches no catch handles it nothing runs here routes 1 and 2 program carries on route 3 leaves the method Answer 3: finally runs on all three routes — even the one nothing catches. Answer 5: on routes 2 and 3 the rest of try never ran, so the division never happened.
Check before Part 4. Can you say all five bold sentences out loud without reading them? Then close the notebook — the next 28 minutes are typed, not written.

PART 4 · PRELAB CODING TASKS · l04-prelab-coding-tasks

Four drills. Each one is a single
move from the graded exercises.

None of these four is marked. Every one of them is a piece of Exercise 1 or Exercise 2, pulled out and practised on its own so that when you meet it inside a bigger program you are not learning two things at once. Build all four in a throwaway project called Lab04Drills, in the default package — no packages until the graded work, so that nothing distracts from the exception itself.

WHAT EACH DRILL REHEARSES

Drill 1 · Catch a NumberFormatException from text that is not a number → EX 1
Drill 2 · Catch an ArrayIndexOutOfBoundsException from an index past the end → EX 2
Drill 3 · Design a checked exception of your own, throw it, declare throws, catch it → EX 1
Drill 4 · Put the cleanup in finally so it runs on both paths → EX 2

FOUR DRILLS · NONE GRADED · ALL FOUR REAPPEAR INSIDE THE TWO GRADED EXERCISES

DRILL 1Catch the text that was never a numberMIRRORS EX 1 · NOT GRADED
PROBLEM

Write ParseDrill .

INPUT

None.

EXPECTED OUTPUT

Not a number: twelve

One line, and the program exits with no red text.

THE ONE IDEA

The try block is not a safety net around your whole program.

Run it once with the try removed first.
try it first — it is eleven lines
DRILL 1 · SOLVED — ONE RISKY LINE, WRAPPED
ECLIPSE SAVES IT AS eclipse-workspace\Lab04Drills\src\ParseDrill.java
ParseDrill.java
1public class ParseDrill
2{
3 public static void main(String[] args)
4 {
5 String typed = "twelve";
6
7 try
8 {
9 int plates = Integer.parseInt(typed);
10 System.out.println("Ordered " + plates + " plates");
11 }
12 catch (NumberFormatException e)
13 {
14 System.out.println("Not a number: " + typed);
15 }
16 }
17}
ECLIPSE CONSOLE
<terminated> ParseDrill [Java Application]
Not a number: twelve
Line 10 never ran.
Seventeen lines, and not one this .
DRILL 2Catch the index that was never thereMIRRORS EX 2 · NOT GRADED
PROBLEM

Write IndexDrill .

INPUT

None.

EXPECTED OUTPUT

No mark 5.

THE ONE IDEA

A good catch block says something the stack trace could not.

Why marks.length and not 3 ?
same shape as Drill 1 — different failure
DRILL 2 · SOLVED — THE SAME SHAPE, A DIFFERENT EXCEPTION
ECLIPSE SAVES IT AS eclipse-workspace\Lab04Drills\src\IndexDrill.java
IndexDrill.java
1public class IndexDrill
2{
3 public static void main(String[] args)
4 {
5 int[] marks = { 41, 38, 45 };
6
7 try
8 {
9 System.out.println(marks[5]);
10 }
11 catch (ArrayIndexOutOfBoundsException e)
12 {
13 System.out.println("No mark 5. List holds " + marks.length);
14 }
15 }
16}
ECLIPSE CONSOLE
<terminated> IndexDrill [Java Application]
No mark 5. List holds 3
Compare this with Drill 1 and notice how little changed.
DRILL 3Design an exception of your ownMIRRORS EX 1 · THE IMPORTANT ONE

This drill is the heart of the lab.

PROBLEM

Two files.

INPUT

None.

EXPECTED OUTPUT

Roll 12 accepted
Rejected: Roll must be positive, got -4

THE ONE IDEA

Declaring throws is a promise to the caller, enforced by the compiler.

MAKE THE COMPILER SHOUT AT YOU ON PURPOSE

Before you write the try / catch in main , type the two checkRoll calls on their own and save.

did the compiler shout at you yet?
DRILL 3 · SOLVED — TWO FILES, ONE PROMISE, ONE super THAT IS NOT OPTIONAL
FILE 1 OF 2 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04Drills\src\InvalidRollException.java
InvalidRollException.java — SEVEN LINES, AND IT IS A COMPLETE EXCEPTION
1public class InvalidRollException extends Exception
2{
3 public InvalidRollException(String message)
4 {
5 super(message);
6 }
7}
WHY THIS IS THE ONE PLACE super IS COMPULSORY
Line 5 is not style.
FILE 2 OF 2 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04Drills\src\RollDrill.java
RollDrill.java
1public class RollDrill
2{
3 public void checkRoll(int roll) throws InvalidRollException
4 {
5 if (roll <= 0)
6 {
7 throw new InvalidRollException("Roll must be positive, got " + roll);
8 }
9 System.out.println("Roll " + roll + " accepted");
10 }
11
12 public static void main(String[] args)
13 {
14 RollDrill desk = new RollDrill();
15
16 try
17 {
18 desk.checkRoll(12);
19 desk.checkRoll(-4);
20 }
21 catch (InvalidRollException e)
22 {
23 System.out.println("Rejected: " + e.getMessage());
24 }
25 }
26}
ECLIPSE CONSOLE
<terminated> RollDrill [Java Application]
Roll 12 accepted
Rejected: Roll must be positive, got -4
Two calls, two outcomes, one catch .
  • line 3 throws InvalidRollException in the signature is a declaration — it warns every caller.
  • line 7 throw new InvalidRollException(...) is the action — it builds an exception object and hands it up.
  • line 3 again checkRoll is not static , so line 14 has to create an object first.
  • DRILL 4Make the cleanup unskippableMIRRORS EX 2 · NOT GRADED
    PROBLEM

    Write FinallyDrill .

    INPUT

    Run it twice .

    EXPECTED OUTPUT

    Run 1: Total 120 rupees
    then -- counter closed --

    Run 2: Digits only, please
    then -- counter closed --

    THE ONE IDEA

    The closing line appears in both runs.

    Then break it on purpose.
    run it twice before you unlock
    DRILL 4 · SOLVED — ONE BLOCK THAT BOTH PATHS MUST PASS THROUGH
    ECLIPSE SAVES IT AS eclipse-workspace\Lab04Drills\src\FinallyDrill.java
    FinallyDrill.java
    1import java.util.Scanner;
    2
    3public class FinallyDrill
    4{
    5 public static void main(String[] args)
    6 {
    7 Scanner sc = new Scanner(System.in);
    8
    9 try
    10 {
    11 System.out.print("Plates: ");
    12 int plates = Integer.parseInt(sc.nextLine());
    13 System.out.println("Total " + (plates * 40) + " rupees");
    14 }
    15 catch (NumberFormatException e)
    16 {
    17 System.out.println("Digits only, please");
    18 }
    19 finally
    20 {
    21 sc.close();
    22 System.out.println("-- counter closed --");
    23 }
    24 }
    25}
    ECLIPSE CONSOLE · BOTH RUNS
    RUN 1 — typed 3
    Plates: 3
    Total 120 rupees
    -- counter closed --
    RUN 2 — typed three
    Plates: three
    Digits only, please
    -- counter closed --
    The last line of both runs is identical.
    All four drills done.

    PART 5 · WALKTHROUGH · l04-walkthrough

    Watch two of them get built,
    one keypress at a time.

    Now the drills get built on the projector, and you build along. Nothing here is new code — it is the order you type it in that matters. Every file in this lab grows the same way: write the risky line first, let it break, then wrap it. Doing it in that order means you see each error attached to the thing that caused it, instead of meeting five at once at the end.

    Step 1 — a throwaway project for the drills

    1

    File › New › Java Project

    Name it Lab04Drills .

    2

    Right-click src › New › Class

    Leave the Package field empty — the drills live in the default package on purpose, so nothing distracts from the exception itself.

    New Java Class

    Java Class

    Create a new Java class.

    Lab04Drills/src
    (default)
    ParseDrill
    public static void main(String[] args)
    Constructors from superclass
    Inherited abstract methods
    CancelFinish
    LEAVE PACKAGE EMPTY FOR THE DRILLS · TICK public static void main — IT SAVES YOU TYPING THE ONE LINE BEGINNERS MISTYPE MOST

    Step 2 — Drill 1, built in two moves

    Move one: type only the risky part. No try, no catch. Five lines inside the method Eclipse already gave you.

    ParseDrill.java — MOVE 1 OF 2, DELIBERATELY UNPROTECTED
    1public class ParseDrill
    2{
    3 public static void main(String[] args)
    4 {
    5 String typed = "twelve";
    6 int plates = Integer.parseInt(typed);
    7 System.out.println("Ordered " + plates + " plates");
    8 }
    9}
    ECLIPSE CONSOLE · PRESS Ctrl + F11
    <terminated> ParseDrill [Java Application]
    Exception in thread "main" java.lang.NumberFormatException: For input string: "twelve"
        at java.base/java.lang.Integer.parseInt(Integer.java:652)
        at java.base/java.lang.Integer.parseInt(Integer.java:770)
        at ParseDrill.main(ParseDrill.java:6)
    Read the red from the bottom up.
    Why show you the crash on purpose?

    Move two: wrap the two lines that must travel together. Line 6 can fail, and line 7 only makes sense if line 6 worked — so both go inside the try, and nothing else does.

    3

    Let Eclipse do it for you, once

    Select lines 6 and 7, then right-click › Surround With › Try/catch Block .

    Run it again.

    Step 3 — Drill 3, and the error you want to see

    Drills 2 and 4 repeat Drill 1's shape — build those at your bench. Drill 3 is worth doing together: the first time the compiler stops you, not the runtime.

    4

    New Class › InvalidRollException — and use the Superclass field

    In the same wizard, click Browse… next to Superclass and type Exception .

    5

    New Class › RollDrill, tick main, then type only lines 3 to 19

    That is: the whole checkRoll method, and the two calls to it in main .

    RollDrill.java — SAVED WITHOUT THE try/catch · TWO RED UNDERLINES
    12 public static void main(String[] args)
    13 {
    14 RollDrill desk = new RollDrill();
    15
    16 desk.checkRoll(12); // red underline
    17 desk.checkRoll(-4); // red underline
    18 }
    19}
    HOVER THE RED UNDERLINE — ECLIPSE SAYS
    Unhandled exception type InvalidRollException
    Nothing ran.
    6

    Now add the try/catch and watch both underlines clear

    Wrap lines 16 and 17 together, and catch InvalidRollException .

    ECLIPSE WILL OFFER YOU A SECOND FIX — DO NOT TAKE IT

    Click the red bulb in the margin and Eclipse offers two Quick Fixes: Surround with try/catch and Add throws declaration .

    Step 4 — now the graded project, with three packages

    Drills sat in the default package because nothing needed a namespace. The graded work does — the Lab 3 habit is not optional from here on. This is the setup you do once, so that Parts 6 and 8 are about exceptions and never about folders.

    7

    File › New › Java Project — named Lab04

    A second , separate project.

    8

    Right-click src › New › Package — three times

    Type the full dotted name into the Name field each time.

    New Java Package

    Java Package

    Create a new Java package.

    Lab04/src
    com.college.admission
    Create package-info.java
    CancelFinish
    REPEAT FOR com.college.bank AND com.college.app · THREE PACKAGES, ONE DOTTED NAME EACH, NEVER TYPED IN PIECES
    File Explorer — what the three wizard runs actually created
    C:\Users\student\eclipse-workspace\Lab04\src
    com
    college
    admission
    app
    bank
    FIVE REAL FOLDERS ON DISK · admission, app AND bank ARE SIBLINGS INSIDE college — NONE IS NESTED INSIDE ANOTHER

    CHECK THIS NOW, NOT AT 3:50 PM

    In Package Explorer, click the three vertical dots › Package Presentation › Hierarchical .

    Step 5 — the order you write the six files in

    This order is not a suggestion. Each file compiles only once the one above it exists — follow it and you never meet an error you cannot explain.

    SIX FILES · IN THIS SEQUENCE

    1 · com.college.admission.InvalidAgeException — nine lines, exactly like Drill 3's file 1 EX 1
    2 · com.college.admission.Student — the rule lives here EX 1
    3 · com.college.app.AdmissionDesk — the program that drives it EX 1
    4 · com.college.bank.InsufficientFundsException — your second custom exception EX 2
    5 · com.college.bank.BankAccount — two rules, two different exception types EX 2
    6 · com.college.app.BankDriver — the array, the multi-catch, the finally EX 2

    EXCEPTION FIRST, THEN THE CLASS THAT THROWS IT, THEN THE PROGRAM THAT CATCHES IT — TWICE

    Why the exception class always comes first.
    If you fall behind at any point from here: the finished code for every drill is in Part 4's solution sheets, and Parts 7 and 9 hold the two graded solutions.

    PART 6 · GRADED · l04-exercise-1-invalid-age

    Exercise 1 · The admissions desk
    that will not accept a negative age.

    Three files, forty-five marks. This is the exam question P2 · Q12b in its real-world form, and every piece of it is something you built in a drill twenty minutes ago. No code is given in this part. Read the specification, write the three files, run it — and only then open Part 7.

    EXERCISE 1InvalidAgeException + Student + AdmissionDesk45 MARKS
    PROBLEM

    File 1 — com.college.admission.InvalidAgeException. A checked exception carrying a message. Same nine-line shape as Drill 3.

    File 2 — Student. Private name and age. A setName. A setAge that throws for a negative age with the number in the message, and otherwise stores it. A printCard.

    File 3 — com.college.app.AdmissionDesk. Name set to Diya Sharma, then loop: prompt for an age and keep prompting until a valid one is entered. Handle the two wrong inputs differently. Print the card.

    INPUT

    Typed at the console. The evaluator tests this exact sequence:

    twenty
    -5
    19

    Three attempts, two rejections, one success.

    EXPECTED OUTPUT

    Enter age: twenty
    Digits only. Try again.
    Enter age: -5
    Rejected: Age cannot be negative: -5
    Enter age: 19
    Diya Sharma | age 19

    The two rejection lines must differ.

    THE ONE IDEA

    Two failures, two causes, two answers. twenty is not a number at all — Java throws NumberFormatException for you. -5 is a valid int; only your college rule makes it wrong, so only your exception can reject it.

    THE FOUR RULES THIS EXERCISE IS ACTUALLY MARKED ON

    • InvalidAgeException extends Exception , not RuntimeException .
    • setAge declares throws InvalidAgeException .
    • No this anywhere in Student .
    • No constructor in Student .
    Before you run it.
    Fifteen of those forty-five are structural — rows 1 and 2 are awarded for a seven-line file and a correct package, both visible before your program is ever run.

    PART 7 · SOLUTION & OUTPUT · l04-exercise-1-solution-output

    Exercise 1, solved — three files,
    and not one wasted keyword.

    Different names and wording are fine. A rule living in the wrong file is not — that is what the marks are for.

    only if you have attempted all three files
    EXERCISE 1 · SOLVED — PYQ P2 · Q12b IN ITS REAL-WORLD FORM
    FILE 1 OF 3 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04\src\com\college\admission\InvalidAgeException.java
    InvalidAgeException.java
    1package com.college.admission;
    2
    3public class InvalidAgeException extends Exception
    4{
    5 public InvalidAgeException(String message)
    6 {
    7 super(message);
    8 }
    9}
    NINE LINES · TEN MARKS
    Line 3 is the whole design decision.
    FILE 2 OF 3 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04\src\com\college\admission\Student.java
    Student.java — THE RULE LIVES HERE, NOT IN THE PROGRAM THAT CALLS IT
    1package com.college.admission;
    2
    3public class Student
    4{
    5 private String name;
    6 private int age;
    7
    8 public void setName(String studentName)
    9 {
    10 name = studentName;
    11 }
    12
    13 public void setAge(int studentAge) throws InvalidAgeException
    14 {
    15 if (studentAge < 0)
    16 {
    17 throw new InvalidAgeException("Age cannot be negative: " + studentAge);
    18 }
    19 age = studentAge;
    20 }
    21
    22 public void printCard()
    23 {
    24 System.out.println(name + " | age " + age);
    25 }
    26}
    READ LINES 10 AND 19 CAREFULLY
    There is no this in this file, and nothing is missing.
  • line 13 The rule and its throws declaration are in Student — the class that owns the data.
  • line 17 The message carries studentAge in it.
  • line 19 This line is only reached when the age is valid.
  • no ctor No constructor anywhere in this file.
  • FILE 3 OF 3 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04\src\com\college\app\AdmissionDesk.java

    The whole file in three sentences, before any detail. It sets up one Student and a flag that starts at false. It then loops, and each time round the loop it asks for an age and tries to set it — flipping the flag to true only if that worked. Because the two ways the input can be wrong are different, they get one catch block each.

    AdmissionDesk.java · PIECE 1 OF 2 — PACKAGE, IMPORTS, SETUP (lines 1–16)
    1package com.college.app;
    2
    3import com.college.admission.InvalidAgeException;
    4import com.college.admission.Student;
    5import java.util.Scanner;
    6
    7public class AdmissionDesk
    8{
    9 public static void main(String[] args)
    10 {
    11 Scanner sc = new Scanner(System.in);
    12 Student diya = new Student();
    13 diya.setName("Diya Sharma");
    14
    15 boolean accepted = false;
    16
    TWO IMPORTS, TWO REASONS
    Line 4 imports the class you use.
    Before you read the loop header — two small things on line 17.
    AdmissionDesk.java · PIECE 2 OF 2 — THE RETRY LOOP (lines 17–40)
    17 while (!accepted)
    18 {
    19 System.out.print("Enter age: ");
    20
    21 try
    22 {
    23 int typed = Integer.parseInt(sc.nextLine());
    24 diya.setAge(typed);
    25 accepted = true;
    26 }
    27 catch (NumberFormatException e)
    28 {
    29 System.out.println("Digits only. Try again.");
    30 }
    31 catch (InvalidAgeException e)
    32 {
    33 System.out.println("Rejected: " + e.getMessage());
    34 }
    35 }
    36
    37 diya.printCard();
    38 sc.close();
    39 }
    40}
    ECLIPSE CONSOLE · THE EVALUATOR'S THREE INPUTS
    <terminated> AdmissionDesk [Java Application]
    Enter age: twenty
    Digits only. Try again.
    Enter age: -5
    Rejected: Age cannot be negative: -5
    Enter age: 19
    Diya Sharma | age 19
    Line 25 is the hinge of the whole program.

    THE ORDER OF THE TWO CATCH BLOCKS — WHY IT DOES NOT MATTER HERE

    NumberFormatException and InvalidAgeException are unrelated : neither is an ancestor of the other.

    Order matters only when one type could catch the other.

    Exercise 1 is done.

    PART 8 · GRADED · l04-exercise-2-banking-multicatch

    Exercise 2 · One counter, several
    things that can go wrong at it.

    Exercise 1 had one custom exception and two failures handled separately. This one has three different failures in one program — one of yours, one of Java's unchecked ones, and one from an array index — plus a finally that must run whatever happens. This is exam question P1 · Q16b in its real-world form. Three more files in the same Lab04 project. No code is given in this part.

    EXERCISE 2BankAccount[] · multi-catch · throws · finally45 MARKS
    PROBLEM

    File 4 — com.college.bank.InsufficientFundsException. A second checked exception, same nine-line shape.

    File 5 — BankAccount. Private holder and balance. An open method setting both. A deposit rejecting a non-positive amount with IllegalArgumentException. A withdraw rejecting an amount above the balance with your exception, reporting the shortfall. A printLine.

    File 6 — com.college.app.BankDriver. A BankAccount[] of 3. One deposit and one withdrawal in a try with a multi-catch; a finally printing a closing line; a second try reaching accounts[5]; then a loop printing all three balances.

    INPUT

    None typed — all hard-coded, so every run is identical.

    Diya Sharma — 5000
    Aarav Reddy — 1200
    Meera Iyer — 800

    Then deposit 2000 into account 0, withdraw 5000 from account 1.

    EXPECTED OUTPUT

    Refused: Short by 3800.0
    -- counter closed --
    No account 5. Bank holds 3
    Diya Sharma : 7000.0
    Aarav Reddy : 1200.0
    Meera Iyer : 800.0

    Six lines. Look hard at the fifth.

    THE ONE IDEA

    A rejected operation must leave nothing half-done. Aarav's withdrawal failed, so his balance must still read 1200.0 — not -3800.0. That depends entirely on where you put the throw.

    THE FIVE RULES THIS EXERCISE IS MARKED ON

    • Two different kinds of exception, on purpose.
    • One multi-catch, using | .
    • finally prints the closing line.
    • The check comes before the change.
    • No this , no constructor, no static field.
    Predict the fifth line before you run.
    Row 2 is the heaviest single row in this lab , and it is not awarded for the throw existing — it is awarded for where it sits.

    PART 9 · SOLUTION & OUTPUT · l04-exercise-2-solution-output

    Exercise 2, solved — and the one
    line that proves nothing was half-done.

    Three files again. The first is nine lines you have now written twice. The interesting one is BankAccount, and the interesting four lines of it are withdraw.

    did you write down Aarav's balance first?
    EXERCISE 2 · SOLVED — PYQ P1 · Q16b IN ITS REAL-WORLD FORM
    FILE 4 OF 6 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04\src\com\college\bank\InsufficientFundsException.java
    InsufficientFundsException.java — THE SAME NINE LINES, A DIFFERENT NAME
    1package com.college.bank;
    2
    3public class InsufficientFundsException extends Exception
    4{
    5 public InsufficientFundsException(String message)
    6 {
    7 super(message);
    8 }
    9}
    THAT IS THE PATTERN, AND IT DOES NOT GROW
    Every custom checked exception you will ever write looks like this.
    FILE 5 OF 6 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04\src\com\college\bank\BankAccount.java

    The whole file in three sentences. It holds a name and a balance, both private. open fills them in; deposit and withdraw each check one rule before changing anything. The two checks throw different kinds of exception on purpose — one of Java's, one of yours — and that difference is the exercise.

    BankAccount.java · PIECE 1 OF 2 — FIELDS, open, deposit (lines 1–21)
    1package com.college.bank;
    2
    3public class BankAccount
    4{
    5 private String holder;
    6 private double balance;
    7
    8 public void open(String holderName, double openingBalance)
    9 {
    10 holder = holderName;
    11 balance = openingBalance;
    12 }
    13
    14 public void deposit(double amount)
    15 {
    16 if (amount <= 0)
    17 {
    18 throw new IllegalArgumentException("Deposit must be positive: " + amount);
    19 }
    20 balance = balance + amount;
    21 }
    LINE 14 HAS NO throws, AND THAT IS CORRECT
    IllegalArgumentException extends RuntimeException , so it is unchecked.
    BankAccount.java · PIECE 2 OF 2 — withdraw, printLine (lines 23–36)
    23 public void withdraw(double amount) throws InsufficientFundsException
    24 {
    25 if (amount > balance)
    26 {
    27 throw new InsufficientFundsException("Short by " + (amount - balance));
    28 }
    29 balance = balance - amount;
    30 }
    31
    32 public void printLine()
    33 {
    34 System.out.println(holder + " : " + balance);
    35 }
    36}
    LINES 25 AND 29 — THE TWELVE-MARK ORDER
    The check is on line 25.
    FILE 6 OF 6 · ECLIPSE SAVES IT AS eclipse-workspace\Lab04\src\com\college\app\BankDriver.java
    BankDriver.java · PIECE 1 OF 3 — THE ARRAY AND THREE ACCOUNTS (lines 1–18)
    1package com.college.app;
    2
    3import com.college.bank.BankAccount;
    4import com.college.bank.InsufficientFundsException;
    5
    6public class BankDriver
    7{
    8 public static void main(String[] args)
    9 {
    10 BankAccount[] accounts = new BankAccount[3];
    11
    12 accounts[0] = new BankAccount();
    13 accounts[0].open("Diya Sharma", 5000);
    14 accounts[1] = new BankAccount();
    15 accounts[1].open("Aarav Reddy", 1200);
    16 accounts[2] = new BankAccount();
    17 accounts[2].open("Meera Iyer", 800);
    18
    LINE 10 CREATES THREE SLOTS, NOT THREE ACCOUNTS
    After line 10 the array exists and every slot holds null .
    BankDriver.java · PIECE 2 OF 3 — MULTI-CATCH AND finally (lines 19–32)
    19 try
    20 {
    21 accounts[0].deposit(2000);
    22 accounts[1].withdraw(5000);
    23 }
    24 catch (IllegalArgumentException | InsufficientFundsException e)
    25 {
    26 System.out.println("Refused: " + e.getMessage());
    27 }
    28 finally
    29 {
    30 System.out.println("-- counter closed --");
    31 }
    32
    LINE 24 — ONE BLOCK, TWO TYPES
    The | reads as “or” : catch either of these.
    BankDriver.java · PIECE 3 OF 3 — THE BAD INDEX AND THE REPORT (lines 33–47)
    33 try
    34 {
    35 accounts[5].printLine();
    36 }
    37 catch (ArrayIndexOutOfBoundsException e)
    38 {
    39 System.out.println("No account 5. Bank holds " + accounts.length);
    40 }
    41
    42 for (int i = 0; i < accounts.length; i++)
    43 {
    44 accounts[i].printLine();
    45 }
    46 }
    47}
    ECLIPSE CONSOLE · ALL SIX LINES
    <terminated> BankDriver [Java Application]
    Refused: Short by 3800.0
    -- counter closed --
    No account 5. Bank holds 3
    Diya Sharma : 7000.0
    Aarav Reddy : 1200.0
    Meera Iyer : 800.0
    The fifth line is the one to read twice.
  • line 35 Reaching for accounts[5] throws before printLine is ever called — the index is evaluated first.
  • line 39accounts.length, never a typed 3 — same rule as Drill 2, and the same rule as never typing 75 inside Lab 3's Main.
  • line 42 The report loop sits outside every try .
  • whole file Zero occurrences of this .
  • PART 10 · DEBRIEF · l04-common-mistakes-debrief-checkpoint

    Seven real errors, the rubric,
    and what to show the evaluator.

    Every message below is one Eclipse actually prints, word for word. Two of the seven produce no message at all — and those are the expensive ones.

    The five the compiler catches for you

    #WHAT YOU DIDWHAT ECLIPSE SAYSFIX
    1Called setAge without handling itUnhandled exception type InvalidAgeExceptionWrap in try/catch, or add throws upstream. Not a bug — the compiler doing the job you asked for.
    2catch (Exception e) before a specific oneUnreachable catch block for NumberFormatExceptionMove the general block to the bottom. Most specific first.
    3Multi-catch with two related typesThe exception NumberFormatException is already caught by the alternative ExceptionMulti-catch types must be siblings. Yours are unrelated, which is why Ex 2 is legal.
    4Caught an exception you never importedInvalidAgeException cannot be resolved to a typeLook at the catch line, not the try. A caught type needs its import too.
    5Wrote throws where you meant throwSyntax error on token "throws", throw expectedthrows declares, in a signature. throw acts, in a body, followed by new.

    IF YOU BUILD FROM THE COMMAND LINE, THE SAME FIVE ERRORS ARE WORDED DIFFERENTLY

    The five messages above are Eclipse's .

    • Mistake 1unreported exception InvalidAgeException; must be caught or declared to be thrown
    • Mistake 2exception NumberFormatException has already been caught
    • Mistake 3Alternatives in a multi-catch statement cannot be related by subclassing
    • Mistake 5illegal start of expression — much less helpful than Eclipse's version, which names the token

    Same error, same fix, different sentence.

    The two the compiler cannot help you with

    These compile cleanly and run — then produce wrong output with total confidence. Same failure mode as Lab 3's NaN. The only defence is reading your own output carefully.

    MISTAKE 6 · THE SUBTRACTION ABOVE THE CHECK

    In withdraw , the balance is changed before the if that guards it.

    Refused: Short by 3800.0 -- counter closed -- No account 5. Bank holds 3 Diya Sharma : 7000.0 Aarav Reddy : -3800.0 Meera Iyer : 800.0

    A refused withdrawal left the account overdrawn.

    MISTAKE 7 · accepted = true TOO EARLY

    In AdmissionDesk , the flag is set immediately after the prompt rather than after both risky calls have succeeded.

    Enter age: twenty Digits only. Try again. Diya Sharma | age 0

    The rejection printed, and the program carried on anyway — admitting a student aged 0, the default of an int field never set. Catching is not recovering.

    THE HABIT THAT CATCHES BOTH OF THESE

    Read your last line of output as if you did not write the program.

    Same discipline as Lab 3: read NaN % Cleared and ask whether a human being would accept that sentence.

    The rubric — 100 marks

    Nothing here is new. This is the two mark-lists from Parts 6 and 8, plus the viva, on one sheet.

    #WHAT IS ASSESSEDDETAILMARKS
    1Ex 1 · the custom exceptionInvalidAgeException extends Exception, String constructor, super(message). Must be checked.10
    2Ex 1 · its packagecom.college.admission in the package line and on disk. Both checked.5
    3Ex 1 · setAgeDeclares throws, throws for a negative age, message names the number. Tested with -5.15
    4Ex 1 · clean Studentprivate fields, no main, no Scanner, no stray this, no constructor.5
    5Ex 1 · two catch blocksSeparate blocks with different messages for twenty and for -5.10
    6Ex 2 · second custom exceptionInsufficientFundsException, checked, in com.college.bank, message reports the shortfall.8
    7Ex 2 · withdraw orderDeclares throws, and the check sits above the line that changes the balance.12
    8Ex 2 · depositThrows IllegalArgumentException and correctly carries no throws clause.8
    9Ex 2 · multi-catch + finallyA real | multi-catch, and the closing line printed from finally.12
    10Ex 2 · index + reportaccounts[5] caught, then three correct balances. Especially Aarav at 1200.0.5
    11VivaTwo or three questions from Part 2 — checked vs unchecked, catch order, what finally guarantees, when to design your own.10
    TOTALExercise 1 · 45  +  Exercise 2 · 45  +  Viva · 10100

    THE THIRTY-ONE MARKS THAT DO NOT DEPEND ON YOUR OUTPUT BEING RIGHT

    Rows 1, 2, 6 and part of 8 total 31 marks, every one awarded for structure: two nine-line exception classes in the right packages, each extends Exception, plus deposit carrying no throws.

    So if you are short of time, write both exception classes first and put them in the right packages .

    What to show the evaluator

    1

    The Package Explorer, in Hierarchical view

    Lab04 › src › com › college with admission, app and bank as three siblings, six files, no red markers.

    2

    Both exception classes open, side by side

    InvalidAgeException.java and InsufficientFundsException.java , both showing extends Exception and both nine lines.

    3

    BankAccount.java open at withdraw

    Lines 23 to 30 on screen, so the check on line 25 and the change on line 29 are visible together.

    4

    Two live runs

    Not screenshots.

    5

    Your notebook, open at the prelab

    The five theory answers from Part 2, in ink, with your corrections in a second colour.

    That is the whole ceremony.

    Your folder after this lab

    File Explorer — what is on your disk when you walk out
    C:\Users\student\eclipse-workspace\Lab04\src
    com
    college
    admission
    InvalidAgeException.java
    Student.java
    app
    AdmissionDesk.java
    BankDriver.java
    bank
    BankAccount.java
    InsufficientFundsException.java
    THREE PACKAGES, SIX FILES · PLUS Lab04Drills WITH THE FIVE UNGRADED DRILL FILES · KEEP BOTH PROJECTS — CLASS 21 USES THEM

    LAB 4 · DONE · SYLLABUS PROGRAMMING EXERCISE 4 CLOSED

    Two custom exceptions, one multi-catch,
    and a bank that refuses cleanly.

    You designed InvalidAgeException and InsufficientFundsExceptionboth checked, both carrying a real message up through super — and drove them from two programs across three packages.

    Four drills got you there one move at a time: bad text, bad index, a checked exception of your own, and a finally that ran on both a good day and a bad one.

    And you closed the crack this lab opened with.

    [FWD → Class 21 · Threads] — and exceptions come with you.

    Bring to Class 21: your Lab04 project.