JAVA-00-Exception
Excellent ⚡ — this is one of the most important and frequently asked Java topics in interviews:
✅ Exception Handling
✅ Custom Exceptions
✅ Error vs Exception
✅ Checked vs Unchecked Exceptions
✅ Best Practices
Let’s go step-by-step from core concepts → custom exception creation → real examples 🔽
🧩 1️⃣ What Is an Exception?
🧠 Definition:
An exception is an event that disrupts the normal flow of a program’s execution.
In Java, all exceptions are objects of classes that inherit from Throwable.
🧩 2️⃣ Exception Hierarchy in Java
java.lang.Object
└── java.lang.Throwable
├── Exception <-- Recoverable issues
│ ├── IOException
│ ├── SQLException
│ ├── ClassNotFoundException
│ └── RuntimeException
│ ├── NullPointerException
│ ├── ArithmeticException
│ ├── IndexOutOfBoundsException
│ └── IllegalArgumentException
│
└── Error <-- Unrecoverable issues
├── OutOfMemoryError
├── StackOverflowError
└── VirtualMachineError
🧩 3️⃣ Exception vs Error
| Feature | Exception | Error |
| Meaning | Problems that can be handled in code | Problems beyond your control |
| Recoverable? | ✅ Yes | ❌ No |
| Examples | IOException, NullPointerException | OutOfMemoryError, StackOverflowError |
| Package | java.lang.Exception | java.lang.Error |
🧩 4️⃣ Checked vs Unchecked Exceptions
| Type | Compile Time? | Example | How to Handle |
| Checked | Checked at compile time | IOException, SQLException | Must use try-catch or throws |
| Unchecked | Checked at runtime | NullPointerException, ArithmeticException | Optional handling |
🧩 5️⃣ Basic Exception Handling Syntax
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero: " + e.getMessage());
} finally {
System.out.println("Finally block always runs");
}
✅ Output:
Cannot divide by zero: / by zero
Finally block always runs
🧩 6️⃣ Common Exception Types
| Exception | When It Occurs |
ArithmeticException | Divide by zero |
NullPointerException | Access null object |
ArrayIndexOutOfBoundsException | Invalid array index |
NumberFormatException | Converting invalid string to number |
IOException | File/stream problems |
SQLException | Database error |
ClassNotFoundException | Missing class |
InterruptedException | Thread interrupted |
🧩 7️⃣ Creating Custom Exceptions
You can create your own exceptions to represent business logic errors or domain-specific problems.
✅ Example 1: Custom Checked Exception
// Step 1: Create custom exception
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
// Step 2: Use it in a class
class Voter {
void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age must be 18 or above to vote");
} else {
System.out.println("You are eligible to vote");
}
}
}
// Step 3: Handle it
public class CustomCheckedExample {
public static void main(String[] args) {
Voter v = new Voter();
try {
v.checkAge(16);
} catch (InvalidAgeException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
✅ Output:
Error: Age must be 18 or above to vote
🧠 Key Points:
Extends
Exception→ checkedMust declare with
throwsCaller must handle with
try-catch
✅ Example 2: Custom Unchecked Exception
// Step 1: Create custom runtime exception
class InsufficientFundsException extends RuntimeException {
public InsufficientFundsException(String message) {
super(message);
}
}
// Step 2: Use it
class Bank {
private double balance = 5000;
void withdraw(double amount) {
if (amount > balance) {
throw new InsufficientFundsException("Not enough balance!");
}
balance -= amount;
System.out.println("Withdrawal successful, remaining: " + balance);
}
}
// Step 3: Test
public class CustomUncheckedExample {
public static void main(String[] args) {
Bank b = new Bank();
b.withdraw(7000); // No try-catch required, unchecked
}
}
✅ Output:
Exception in thread "main" InsufficientFundsException: Not enough balance!
🧠 Key Points:
Extends
RuntimeException→ uncheckedNo
throwsdeclaration requiredUsually used for programming logic errors
🧩 8️⃣ throw vs throws
| Keyword | Used For | Example |
throw | To manually throw an exception | throw new IOException("error") |
throws | To declare an exception | void readFile() throws IOException |
✅ Example:
void m1() throws IOException {
throw new IOException("File missing");
}
🧩 9️⃣ try-with-resources (AutoCloseable)
Introduced in Java 7 — automatically closes files, streams, DB connections.
✅ Example:
import java.io.*;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
System.out.println(br.readLine());
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
}
}
✅ The resource (BufferedReader) closes automatically — no finally needed.
🧩 🔟 Multi-Catch Block
You can catch multiple exceptions in one block (Java 7+).
try {
int a = 10 / 0;
int[] arr = new int[2];
arr[3] = 5;
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("Error: " + e.getClass().getSimpleName());
}
🧩 11️⃣ Exception Propagation
When an exception is not caught, it propagates up the call stack.
class Test {
void m1() {
int x = 10 / 0; // ArithmeticException
}
void m2() {
m1();
}
void m3() {
try {
m2();
} catch (Exception e) {
System.out.println("Caught in m3");
}
}
}
public class PropagationDemo {
public static void main(String[] args) {
new Test().m3();
}
}
✅ Output:
Caught in m3
🧩 12️⃣ Custom Exception Best Practices
✅ Always extend Exception or RuntimeException.
✅ Provide meaningful names like UserNotFoundException.
✅ Include constructors with message & cause.
✅ Never create unnecessary custom exceptions — reuse standard ones if possible.
✅ Log the full stack trace before handling critical exceptions.
🧩 13️⃣ Example: Advanced Custom Exception with Cause
class DataNotFoundException extends Exception {
public DataNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
public class AdvancedCustom {
public static void main(String[] args) {
try {
readFile();
} catch (DataNotFoundException e) {
e.printStackTrace();
}
}
static void readFile() throws DataNotFoundException {
try {
throw new java.io.FileNotFoundException("File missing");
} catch (java.io.FileNotFoundException e) {
throw new DataNotFoundException("Unable to find user data", e);
}
}
}
✅ Output:
DataNotFoundException: Unable to find user data
at AdvancedCustom.readFile(AdvancedCustom.java:...)
Caused by: java.io.FileNotFoundException: File missing
🧩 14️⃣ Summary (Interview Revision)
| Concept | Example | Notes |
| Exception | ArithmeticException | Recoverable |
| Error | OutOfMemoryError | Unrecoverable |
| Checked | IOException | Compile-time check |
| Unchecked | NullPointerException | Runtime check |
| Custom Checked | extends Exception | Must handle or declare |
| Custom Unchecked | extends RuntimeException | Optional handling |
| throw | To throw exception manually | throw new Exception() |
| throws | Declare method may throw | void m() throws Exception |
| try-with-resources | Auto-close resources | Java 7+ |
| finally | Always executes | Clean-up code |
✅ Next Step (Optional):
Would you like me to give a complete real-world mini project that uses:
custom checked + unchecked exceptions
file reading + validation
exception chaining + try-with-resources
(all in one complete example)?
It’s the same type of question often asked in advanced Java interviews.
You said:
yes
ChatGPT said:
Perfect 🔥 — Let’s build a real-world mini Java project that combines everything you learned about exceptions:
We’ll create a User Registration System that demonstrates:
✅ Checked + Unchecked Custom Exceptions
✅ try-with-resources
✅ throw vs throws
✅ Exception chaining (cause)
✅ File reading and validation
🧩 Project: “User Registration Validator”
📁 Use Case
You have a file named users.txt containing user data:
John,25
Amy,17
Sam,-5
Riya,abc
You want to:
Read each line from the file
Validate the name and age
Throw proper custom exceptions if something goes wrong
Handle all errors gracefully
🧩 Step 1: Define Custom Exceptions
// Checked Exception - for invalid data
class InvalidUserDataException extends Exception {
public InvalidUserDataException(String message) {
super(message);
}
public InvalidUserDataException(String message, Throwable cause) {
super(message, cause);
}
}
// Unchecked Exception - for critical runtime issues
class UserSystemFailureException extends RuntimeException {
public UserSystemFailureException(String message) {
super(message);
}
}
🧩 Step 2: Create the Main Logic
import java.io.*;
import java.util.*;
public class UserRegistrationSystem {
public static void main(String[] args) {
String filePath = "users.txt"; // Your input file
try {
processUserFile(filePath);
} catch (InvalidUserDataException e) {
System.out.println("Validation Error: " + e.getMessage());
} catch (UserSystemFailureException e) {
System.out.println("System Failure: " + e.getMessage());
} finally {
System.out.println("Processing finished ✅");
}
}
static void processUserFile(String filePath) throws InvalidUserDataException {
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
int lineNumber = 1;
while ((line = br.readLine()) != null) {
validateUser(line, lineNumber);
lineNumber++;
}
} catch (FileNotFoundException e) {
// Wrap low-level exception into custom checked exception
throw new InvalidUserDataException("File not found: " + filePath, e);
} catch (IOException e) {
throw new UserSystemFailureException("Unexpected I/O error while reading file.");
}
}
static void validateUser(String userData, int lineNumber) throws InvalidUserDataException {
try {
String[] parts = userData.split(",");
String name = parts[0].trim();
String ageStr = parts[1].trim();
if (name.isEmpty()) {
throw new InvalidUserDataException("Line " + lineNumber + ": Name cannot be empty");
}
int age = Integer.parseInt(ageStr);
if (age < 0) {
throw new InvalidUserDataException("Line " + lineNumber + ": Age cannot be negative");
}
if (age < 18) {
throw new InvalidUserDataException("Line " + lineNumber + ": User is under 18");
}
System.out.println("✅ Registered: " + name + " (Age: " + age + ")");
} catch (NumberFormatException e) {
throw new InvalidUserDataException("Line " + lineNumber + ": Invalid age format", e);
} catch (ArrayIndexOutOfBoundsException e) {
throw new InvalidUserDataException("Line " + lineNumber + ": Missing name or age", e);
}
}
}
🧩 Step 3: Output Example
Given the file:
John,25
Amy,17
Sam,-5
Riya,abc
✅ Output:
✅ Registered: John (Age: 25)
Validation Error: Line 2: User is under 18
Processing finished ✅
🧠 Concept Breakdown
| Concept | Demonstrated Where | Description |
| Checked Exception | InvalidUserDataException | Must be declared with throws |
| Unchecked Exception | UserSystemFailureException | For unexpected runtime errors |
| throw | Inside validateUser() | Manually throwing exception |
| throws | On processUserFile() method | Declaring it may throw |
| try-with-resources | BufferedReader br = new ... | Automatically closes file |
| Exception chaining | throw new InvalidUserDataException(..., e) | Pass original cause |
| finally block | In main() | Always executes |
🧩 Step 4: How to Extend Further
You can add:
Logging (using
java.util.loggingor Log4j)Retry mechanism
Write invalid records to a new file (
invalid_users.txt)Use
CustomExceptionhierarchy (e.g.AgeValidationException,NameValidationException)
🧩 Step 5: Interview Summary Points
✅ Checked Exception → compile-time validation
✅ Unchecked Exception → runtime issue
✅ throw → raise exception
✅ throws → declare exception
✅ try-with-resources → auto resource cleanup
✅ Custom Exception → domain-specific validation
✅ Exception chaining → preserve root cause
✅ Use checked for recoverable conditions, unchecked for logical bugs