Practice Questions — Exception Handling in Java
← Back to NotesTopic-Specific Questions
Question 1
Easy
What is the output?
public class Main {
public static void main(String[] args) {
try {
System.out.println("Before");
int result = 10 / 0;
System.out.println("After");
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("End");
}
}The line after the exception is not executed. Control jumps to the catch block.
BeforeError: / by zeroEndQuestion 2
Easy
What is the output?
public class Main {
public static void main(String[] args) {
try {
System.out.println("Try");
} catch (Exception e) {
System.out.println("Catch");
} finally {
System.out.println("Finally");
}
}
}No exception is thrown. Does the finally block still execute?
TryFinallyQuestion 3
Easy
What is the output?
public class Main {
public static void main(String[] args) {
try {
String s = null;
System.out.println(s.length());
} catch (NullPointerException e) {
System.out.println("Caught NPE");
}
}
}Calling a method on null throws NullPointerException.
Caught NPEQuestion 4
Easy
What is the output?
public class Main {
public static void main(String[] args) {
try {
int num = Integer.parseInt("123");
System.out.println("Parsed: " + num);
} catch (NumberFormatException e) {
System.out.println("Not a number");
}
}
}"123" is a valid integer string. Does an exception occur?
Parsed: 123Question 5
Easy
What is the output?
public class Main {
public static void main(String[] args) {
try {
int[] arr = new int[3];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
System.out.println(arr[1]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Out of bounds");
}
}
}All array indices (0, 1, 2) are valid for an array of size 3.
20Question 6
Medium
What is the output?
public class Main {
public static void main(String[] args) {
try {
System.out.println("A");
int x = 10 / 0;
System.out.println("B");
} catch (ArithmeticException e) {
System.out.println("C");
} finally {
System.out.println("D");
}
System.out.println("E");
}
}Trace the flow: try -> exception -> catch -> finally -> after.
ACDEQuestion 7
Medium
What is the output?
public class Main {
static int divide(int a, int b) {
return a / b;
}
public static void main(String[] args) {
try {
System.out.println(divide(10, 2));
System.out.println(divide(10, 0));
System.out.println(divide(20, 4));
} catch (ArithmeticException e) {
System.out.println("Division error");
}
System.out.println("Done");
}
}The second call throws. Does the third call execute?
5Division errorDoneQuestion 8
Medium
What is the output?
public class Main {
public static void main(String[] args) {
for (String s : new String[]{"10", "abc", "20"}) {
try {
int n = Integer.parseInt(s);
System.out.println("Parsed: " + n);
} catch (NumberFormatException e) {
System.out.println("Invalid: " + s);
}
}
}
}The try-catch is inside the loop. Each iteration is independent.
Parsed: 10Invalid: abcParsed: 20Question 9
Medium
What is the output?
public class Main {
static int getValue() {
try {
System.out.println("try");
return 1;
} catch (Exception e) {
System.out.println("catch");
return 2;
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
System.out.println("Value: " + getValue());
}
}finally executes even when there is a return in try.
tryfinallyValue: 1Question 10
Medium
What is the output?
class CustomException extends Exception {
CustomException(String msg) { super(msg); }
}
public class Main {
static void check(int x) throws CustomException {
if (x < 0) throw new CustomException("Negative: " + x);
System.out.println("Value: " + x);
}
public static void main(String[] args) {
try {
check(5);
check(-3);
check(10);
} catch (CustomException e) {
System.out.println("Caught: " + e.getMessage());
}
}
}check(5) works. check(-3) throws. Does check(10) run?
Value: 5Caught: Negative: -3Question 11
Hard
What is the output?
public class Main {
static void methodC() {
System.out.println("C start");
throw new RuntimeException("Error in C");
}
static void methodB() {
System.out.println("B start");
methodC();
System.out.println("B end");
}
static void methodA() {
System.out.println("A start");
try {
methodB();
} catch (RuntimeException e) {
System.out.println("Caught: " + e.getMessage());
}
System.out.println("A end");
}
public static void main(String[] args) {
methodA();
}
}The exception propagates from C through B to A where it is caught.
A startB startC startCaught: Error in CA endQuestion 12
Hard
What is the output?
public class Main {
public static void main(String[] args) {
try {
try {
throw new RuntimeException("inner");
} catch (RuntimeException e) {
System.out.println("Inner catch: " + e.getMessage());
throw new RuntimeException("rethrown");
} finally {
System.out.println("Inner finally");
}
} catch (RuntimeException e) {
System.out.println("Outer catch: " + e.getMessage());
} finally {
System.out.println("Outer finally");
}
}
}The inner catch rethrows a new exception. Inner finally runs first, then outer catch.
Inner catch: innerInner finallyOuter catch: rethrownOuter finallyQuestion 13
Hard
What is the output?
class Resource implements AutoCloseable {
String name;
Resource(String name) {
this.name = name;
System.out.println(name + " opened");
}
public void close() {
System.out.println(name + " closed");
}
}
public class Main {
public static void main(String[] args) {
try (Resource r1 = new Resource("A");
Resource r2 = new Resource("B")) {
System.out.println("Using resources");
throw new RuntimeException("Failure");
} catch (RuntimeException e) {
System.out.println("Error: " + e.getMessage());
}
}
}Resources are closed in reverse order before the catch block runs.
A openedB openedUsing resourcesB closedA closedError: FailureQuestion 14
Hard
What is the output?
public class Main {
static String test() {
String result = "initial";
try {
result = "try";
return result;
} finally {
result = "finally";
}
}
public static void main(String[] args) {
System.out.println(test());
}
}The return value is evaluated before finally runs. Does changing result in finally affect the returned value?
tryQuestion 15
Hard
What is the output?
public class Main {
public static void main(String[] args) {
try {
System.out.println("try");
System.exit(0);
} finally {
System.out.println("finally");
}
}
}System.exit() terminates the JVM. What happens to finally?
tryQuestion 16
Hard
What is the output?
public class Main {
public static void main(String[] args) {
try {
throw new RuntimeException("first");
} catch (RuntimeException e) {
System.out.println(e.getMessage());
throw new RuntimeException("second");
} finally {
System.out.println("finally");
throw new RuntimeException("third");
}
}
}An exception in finally replaces the exception from catch.
firstfinallyThen the program terminates with
RuntimeException: thirdMixed & Application Questions
Question 1
Easy
What is the difference between checked and unchecked exceptions?
Think about what the compiler requires.
Checked exceptions (subclasses of Exception, excluding RuntimeException) must be caught or declared with
throws. The compiler enforces this. Unchecked exceptions (subclasses of RuntimeException) do not require handling. Checked exceptions represent recoverable conditions (file not found); unchecked exceptions represent programming errors (null pointer).Question 2
Easy
What is the difference between
throw and throws?One is used inside the method body, the other in the method signature.
throw is used inside a method to explicitly throw an exception object: throw new Exception("error"). throws is used in the method signature to declare that the method might throw certain checked exceptions: void read() throws IOException.Question 3
Easy
What is the output?
public class Main {
public static void main(String[] args) {
try {
System.out.println(1);
System.out.println(2);
System.out.println(3);
} catch (Exception e) {
System.out.println("Error");
}
System.out.println(4);
}
}No exception is thrown. What happens?
1234Question 4
Medium
What is the output?
public class Main {
public static void main(String[] args) {
int x = 0;
try {
x = 1;
int[] arr = null;
x = arr.length;
x = 2;
} catch (NullPointerException e) {
x = 3;
} finally {
x = 4;
}
System.out.println(x);
}
}Trace the value of x through try, catch, and finally.
4Question 5
Medium
What is exception propagation?
Think about what happens when a method does not catch an exception.
Exception propagation is the process where an unhandled exception moves up the call stack from the method where it was thrown, through each calling method, until it finds a matching catch block. If no method catches it, the JVM prints the stack trace and terminates the program.
Question 6
Medium
What is the output?
public class Main {
public static void main(String[] args) {
try {
String s = "Hello";
char c = s.charAt(10);
} catch (StringIndexOutOfBoundsException e) {
System.out.println("String error");
} catch (Exception e) {
System.out.println("General error");
}
}
}"Hello" has indices 0-4. Index 10 is out of bounds.
String errorQuestion 7
Medium
What is the output?
public class Main {
static void risky() throws Exception {
throw new Exception("Problem!");
}
static void caller() {
try {
risky();
} catch (Exception e) {
System.out.println("Handled: " + e.getMessage());
}
}
public static void main(String[] args) {
caller();
System.out.println("Done");
}
}risky() declares throws Exception. caller() catches it.
Handled: Problem!DoneQuestion 8
Hard
What is the output?
public class Main {
static int count = 0;
static void recursive() {
count++;
recursive();
}
public static void main(String[] args) {
try {
recursive();
} catch (StackOverflowError e) {
System.out.println("Stack overflow after " + count + " calls");
}
}
}Infinite recursion causes StackOverflowError. Can it be caught?
Stack overflow after [some large number] callsQuestion 9
Hard
When should you create a checked custom exception vs an unchecked custom exception?
Think about whether the caller can reasonably recover from the error.
Use a checked exception (extend
Exception) when the caller can and should recover from the condition: insufficient funds, file not found, invalid input from an external source. Use an unchecked exception (extend RuntimeException) when the error represents a programming bug that should be fixed in the code: null argument, invalid state, assertion failure.Question 10
Hard
What is the output?
public class Main {
static void method() {
try {
throw new RuntimeException("A");
} catch (RuntimeException e) {
System.out.println(e.getMessage());
throw new RuntimeException("B");
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
try {
method();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
}Exception B is thrown from catch. Finally runs before it propagates.
AfinallyBQuestion 11
Medium
What is try-with-resources and what interface must a resource implement?
Think about automatic resource cleanup.
Try-with-resources (Java 7) is a try statement that declares one or more resources in its header. Resources are automatically closed when the try block exits, even if an exception occurs. Resources must implement the
AutoCloseable interface (which has a single close() method).Question 12
Hard
What is the output?
public class Main {
public static void main(String[] args) {
System.out.println(test());
}
static int test() {
int x = 0;
try {
x = 1;
return x;
} finally {
x = 2;
return x;
}
}
}The return in finally overrides the return in try.
2Multiple Choice Questions
MCQ 1
Which block always executes regardless of whether an exception occurs?
Answer: C
C is correct. The
C is correct. The
finally block always executes, whether an exception occurred or not, whether it was caught or not. The only exceptions are System.exit() and JVM crashes.MCQ 2
Which of these is a checked exception?
Answer: B
B is correct.
B is correct.
IOException is a checked exception (extends Exception, not RuntimeException). The other three are unchecked (subclasses of RuntimeException).MCQ 3
What is the parent class of all exceptions and errors in Java?
Answer: C
C is correct.
C is correct.
Throwable is the root of the exception hierarchy. Both Exception and Error extend Throwable. While Object is the ultimate parent, Throwable is the root of throwable types.MCQ 4
What does the
throw keyword do?Answer: B
B is correct.
B is correct.
throw explicitly creates and throws an exception object: throw new Exception("error"). throws (with 's') is used in the method signature for declaration.MCQ 5
NullPointerException is a:
Answer: B
B is correct.
B is correct.
NullPointerException extends RuntimeException, making it an unchecked exception. The compiler does not force you to catch it.MCQ 6
What interface must a resource implement to be used in try-with-resources?
Answer: B
B is correct. Resources in try-with-resources must implement
B is correct. Resources in try-with-resources must implement
AutoCloseable (which has a close() method). Closeable extends AutoCloseable, so Closeable resources also work.MCQ 7
What happens if a checked exception is neither caught nor declared with throws?
Answer: C
C is correct. Checked exceptions must be either caught (try-catch) or declared (throws in signature). Failing to do either results in a compilation error.
C is correct. Checked exceptions must be either caught (try-catch) or declared (throws in signature). Failing to do either results in a compilation error.
MCQ 8
In multi-catch, which separator is used between exception types?
Answer: C
C is correct. Multi-catch uses the pipe operator
C is correct. Multi-catch uses the pipe operator
|: catch (IOException | SQLException e). The exception types must not have a parent-child relationship.MCQ 9
To create a custom checked exception, you should extend:
Answer: B
B is correct. Extending
B is correct. Extending
Exception creates a checked exception. Extending RuntimeException creates an unchecked exception. Extending Error is for JVM-level issues.MCQ 10
What is exception propagation?
Answer: B
B is correct. When a method does not catch an exception, it propagates to the calling method. This continues up the call stack until it is caught or the program terminates.
B is correct. When a method does not catch an exception, it propagates to the calling method. This continues up the call stack until it is caught or the program terminates.
MCQ 11
What happens to the return value if finally has a return statement?
Answer: C
C is correct. A return in the finally block overrides any return from try or catch. This is confusing behavior, which is why returning from finally is strongly discouraged.
C is correct. A return in the finally block overrides any return from try or catch. This is confusing behavior, which is why returning from finally is strongly discouraged.
MCQ 12
Can you have a try block without a catch block?
Answer: B
B is correct. A try block must be followed by either a catch block, a finally block, or both.
B is correct. A try block must be followed by either a catch block, a finally block, or both.
try { } finally { } is valid. Also, try-with-resources can omit both catch and finally.MCQ 13
What exception does
Integer.parseInt("abc") throw?Answer: B
B is correct.
B is correct.
parseInt throws NumberFormatException when the string cannot be parsed as an integer. NumberFormatException is a subclass of IllegalArgumentException.MCQ 14
In try-with-resources with multiple resources, what order are they closed?
Answer: B
B is correct. Resources in try-with-resources are closed in reverse order of their declaration. This matches the stack-like nature of resource acquisition (last acquired, first released).
B is correct. Resources in try-with-resources are closed in reverse order of their declaration. This matches the stack-like nature of resource acquisition (last acquired, first released).
MCQ 15
Which of the following is TRUE about Error in Java?
Answer: C
C is correct.
C is correct.
Error represents serious JVM-level problems (OutOfMemoryError, StackOverflowError) that applications should not attempt to catch. They extend Throwable, not RuntimeException.MCQ 16
What is the purpose of the
getMessage() method in exceptions?Answer: B
B is correct.
B is correct.
getMessage() returns the detail message string passed to the exception's constructor. For new Exception("file not found"), getMessage() returns "file not found".Coding Challenges
Challenge 1: Safe Division Calculator
EasyWrite a method safeDivide(int a, int b) that returns the result of a/b. If b is 0, catch the ArithmeticException and return -1. Test with (10,2), (10,0), (20,4).
Sample Input
(10,2), (10,0), (20,4)
Sample Output
10 / 2 = 5
10 / 0 = -1 (division by zero)
20 / 4 = 5
Use try-catch. Return -1 on error.
public class Main {
static int safeDivide(int a, int b) {
try {
return a / b;
} catch (ArithmeticException e) {
return -1;
}
}
public static void main(String[] args) {
int[][] tests = {{10,2}, {10,0}, {20,4}};
for (int[] t : tests) {
int result = safeDivide(t[0], t[1]);
if (result == -1) {
System.out.println(t[0] + " / " + t[1] + " = -1 (division by zero)");
} else {
System.out.println(t[0] + " / " + t[1] + " = " + result);
}
}
}
}Challenge 2: Input Validator with Custom Exceptions
MediumCreate two custom exceptions: InvalidAgeException and InvalidNameException. Write a method registerStudent(String name, int age) that throws InvalidNameException if name is null/empty, and InvalidAgeException if age is not between 5 and 25. Test with valid and invalid inputs.
Sample Input
('Arjun', 20), ('', 20), ('Kavya', -5), (null, 30)
Sample Output
Registered: Arjun, age 20
Error: Name cannot be empty
Error: Invalid age: -5. Must be between 5 and 25
Error: Name cannot be null
Custom exceptions must extend Exception (checked). Include meaningful messages.
class InvalidAgeException extends Exception {
InvalidAgeException(int age) {
super("Invalid age: " + age + ". Must be between 5 and 25");
}
}
class InvalidNameException extends Exception {
InvalidNameException(String reason) {
super(reason);
}
}
public class Main {
static void registerStudent(String name, int age) throws InvalidNameException, InvalidAgeException {
if (name == null) throw new InvalidNameException("Name cannot be null");
if (name.isEmpty()) throw new InvalidNameException("Name cannot be empty");
if (age < 5 || age > 25) throw new InvalidAgeException(age);
System.out.println("Registered: " + name + ", age " + age);
}
public static void main(String[] args) {
Object[][] tests = {{"Arjun", 20}, {"", 20}, {"Kavya", -5}, {null, 30}};
for (Object[] t : tests) {
try {
registerStudent((String) t[0], (int) t[1]);
} catch (InvalidNameException | InvalidAgeException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
}Challenge 3: Resource Manager with AutoCloseable
MediumCreate a class ConnectionPool implementing AutoCloseable. It has a constructor that prints 'Pool opened with N connections', a method getConnection(int id) that throws RuntimeException if id > pool size, and close() that prints 'Pool closed'. Demonstrate try-with-resources with normal use and with an exception.
Sample Input
Pool size=3, get connections 1, 2, 5
Sample Output
Pool opened with 3 connections
Connection 1 acquired
Connection 2 acquired
Pool closed
Error: Connection 5 exceeds pool size 3
Implement AutoCloseable. Use try-with-resources.
class ConnectionPool implements AutoCloseable {
int size;
ConnectionPool(int size) {
this.size = size;
System.out.println("Pool opened with " + size + " connections");
}
void getConnection(int id) {
if (id > size) throw new RuntimeException("Connection " + id + " exceeds pool size " + size);
System.out.println("Connection " + id + " acquired");
}
@Override
public void close() {
System.out.println("Pool closed");
}
}
public class Main {
public static void main(String[] args) {
try (ConnectionPool pool = new ConnectionPool(3)) {
pool.getConnection(1);
pool.getConnection(2);
pool.getConnection(5);
} catch (RuntimeException e) {
System.out.println("Error: " + e.getMessage());
}
}
}Challenge 4: Exception Chain Logger
HardWrite three methods: parseData() throws NumberFormatException, processData() calls parseData and wraps the exception in a custom DataProcessingException (with the original as cause), and main() catches DataProcessingException and prints both the message and the root cause.
Sample Input
Input: "abc"
Sample Output
Processing error: Failed to process data
Root cause: NumberFormatException: For input string: "abc"
Use exception chaining (pass cause to constructor). Access with getCause().
class DataProcessingException extends Exception {
DataProcessingException(String msg, Throwable cause) {
super(msg, cause);
}
}
public class Main {
static int parseData(String input) {
return Integer.parseInt(input);
}
static int processData(String input) throws DataProcessingException {
try {
return parseData(input);
} catch (NumberFormatException e) {
throw new DataProcessingException("Failed to process data", e);
}
}
public static void main(String[] args) {
try {
processData("abc");
} catch (DataProcessingException e) {
System.out.println("Processing error: " + e.getMessage());
System.out.println("Root cause: " + e.getCause().getClass().getSimpleName() + ": " + e.getCause().getMessage());
}
}
}Challenge 5: Bank Transaction System
HardCreate a BankAccount class with methods deposit(double) and withdraw(double). Withdraw throws InsufficientFundsException (custom checked) if amount > balance. Write a transfer(BankAccount from, BankAccount to, double amount) method. If withdraw fails, the transfer should be atomic (no partial changes). Test with successful and failed transfers.
Sample Input
Account A: 5000, Account B: 3000, Transfer 2000 then 5000
Sample Output
Transfer of 2000.0: Success
A: 3000.0, B: 5000.0
Transfer of 5000.0: Failed - Insufficient funds. Deficit: 2000.0
A: 3000.0, B: 5000.0
Ensure atomicity: if withdraw fails, no changes should persist.
class InsufficientFundsException extends Exception {
double deficit;
InsufficientFundsException(double deficit) {
super("Insufficient funds. Deficit: " + deficit);
this.deficit = deficit;
}
}
class BankAccount {
String name;
double balance;
BankAccount(String name, double balance) {
this.name = name;
this.balance = balance;
}
void deposit(double amount) { balance += amount; }
void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) throw new InsufficientFundsException(amount - balance);
balance -= amount;
}
}
public class Main {
static void transfer(BankAccount from, BankAccount to, double amount) {
try {
from.withdraw(amount);
to.deposit(amount);
System.out.println("Transfer of " + amount + ": Success");
} catch (InsufficientFundsException e) {
System.out.println("Transfer of " + amount + ": Failed - " + e.getMessage());
}
System.out.println(from.name + ": " + from.balance + ", " + to.name + ": " + to.balance);
}
public static void main(String[] args) {
BankAccount a = new BankAccount("A", 5000);
BankAccount b = new BankAccount("B", 3000);
transfer(a, b, 2000);
transfer(a, b, 5000);
}
}Need to Review the Concepts?
Go back to the detailed notes for this chapter.
Read Chapter NotesWant to learn Java with a live mentor?
Explore our Java Masterclass