Hello dear students! Today we are going to study a very important chapter called Exception Handling. Have you ever written a program that was running fine and then suddenly stopped with some red error messages? That usually means an exception happened. In this lesson, I will teach you how to handle those errors gracefully so your program does not crash. This topic carries good marks in your exam, so please study each section carefully.
What is an Exception?
Let me start with a simple question. What do you think happens when you try to divide a number by zero in Java? Or what happens when you try to access an array element at index 10 when the array only has 5 elements? The program suddenly stops running and shows an error message. That error is called an exception.
An exception is an unwanted or unexpected event that happens during the execution of a program. It disrupts the normal flow of the program instructions. When an exception occurs, Java creates an exception object that contains information about the error, like the error name, the message, and the line number where it happened. This object is then “thrown” and the program looks for someone to “catch” it.
Let me show you what happens without exception handling:
Output:
See what happened? The program crashed at line 4 and the lines after it never executed. The error message tells us the exception name is ArithmeticException and the reason is “/ by zero”. This is a problem because in a real application, we do not want the entire program to crash just because of one bad division. We want to handle the error, show a friendly message to the user, and let the rest of the program continue. That is exactly what exception handling does for us.
1. An exception is an abnormal event that disrupts the normal flow of program execution.
2. When an exception occurs, Java creates an exception object that contains error details.
3. Without exception handling, the program crashes at the line where the exception occurs.
4. Lines of code after the exception line do not execute.
5. Exception handling allows the program to recover from the error and continue running.
Question 1: What happens when an exception occurs in a Java program and is not handled?
A) The program skips the bad line and continues B) The program prints a warning and continues C) The program terminates abruptly D) The program restarts automatically
Answer: C) The program terminates abruptly
When an exception occurs and there is no code to handle it, the Java runtime system catches it and prints the error message along with the stack trace showing where the exception happened. Then it immediately terminates the program. None of the code after the exception line gets a chance to run. This is why we need exception handling, to prevent this sudden termination and allow the program to recover gracefully.
Question 2: When an exception occurs in Java, an ________ object is created that contains information about the error.
Answer: exception
Java creates an exception object (an instance of a subclass of Throwable) that contains important information about the error: the name of the exception, a descriptive message, and the stack trace showing which methods were called and on which line the exception occurred. This object is then thrown up through the call stack until it is caught by an appropriate handler.
Types of Errors in Java
Before we go deep into exceptions, let me clarify the different types of errors you can encounter in Java. Students often confuse these in exams, so pay close attention.
1. Compile-Time Errors (Syntax Errors)
These errors are detected by the Java compiler before the program runs. They happen when you write code that does not follow Java syntax rules. For example, missing a semicolon, using a variable without declaring it, mismatched brackets, or misspelling a keyword.
These errors must be fixed before the program can run at all. The compiler will not produce a .class file if there are compile-time errors.
2. Runtime Errors (Exceptions)
These errors happen while the program is running. The program compiles fine (no syntax errors), but something goes wrong during execution. For example, dividing by zero, accessing an invalid array index, or trying to access a null object. These are the errors that exception handling deals with.
3. Logical Errors
These errors happen when the program compiles and runs without crashing, but produces wrong results. The logic of your code is incorrect. For example, using a plus sign instead of a minus sign in a calculation. Java cannot detect these for you. You must find them yourself through testing.
1. Compile-time errors are caught by the compiler before running. They are syntax errors.
2. Runtime errors happen during execution. They are the exceptions we handle using try-catch.
3. Logical errors produce wrong results but do not crash the program. Java cannot detect them.
4. Exception handling deals ONLY with runtime errors, not compile-time or logical errors.
5. A common exam question is to identify which type of error a given code has.
Question 3: Which type of error can be handled using exception handling in Java?
A) Missing semicolon B) Dividing an integer by zero C) Using + instead of * for multiplication D) Undefined variable name
Answer: B) Dividing an integer by zero
Option A is a compile-time error (missing semicolon). Option C is a logical error (wrong operator, but the program runs). Option D is a compile-time error (undefined variable). Only option B is a runtime error that causes an ArithmeticException at runtime, which can be handled using try-catch blocks. Exception handling in Java is designed specifically to deal with runtime errors.
Question 4: Identify the type of error in the following code: int result = 10 / 0;
Answer: Runtime Error (Exception)
The code int result = 10 / 0; has no syntax errors, so it compiles successfully. The error only happens when the program tries to execute the division by zero. At that point, Java throws an ArithmeticException. Since this error occurs during program execution (not at compile time), it is classified as a runtime error, and it can be handled using exception handling mechanisms like try-catch.
Exception Hierarchy in Java
Now let me explain the exception hierarchy because examiners love to ask about this. All exceptions and errors in Java are organized in a class hierarchy. At the very top is a class called Throwable. Everything that can be thrown in Java is a subclass of Throwable.
Let me explain the main branches:
Error: Errors are serious problems that a program usually cannot recover from. Examples include OutOfMemoryError (when the JVM runs out of memory) and StackOverflowError (when a method calls itself too many times, creating infinite recursion). We do NOT try to handle errors using try-catch. They indicate problems with the system itself, not with our code logic.
Exception: Exceptions are problems that a program can potentially recover from. Exceptions are further divided into two categories:
- Checked Exceptions: These are exceptions that the compiler forces you to handle. If your code might throw a checked exception, you MUST either catch it with try-catch or declare it with throws. Otherwise, the program will not compile. Examples:
IOException,FileNotFoundException,SQLException. They are called “checked” because the compiler checks for them at compile time. - Unchecked Exceptions: These are exceptions that the compiler does NOT force you to handle. They occur due to programming mistakes (like dividing by zero or accessing a null object). The compiler will not complain if you do not handle them. All subclasses of
RuntimeExceptionare unchecked. Examples:ArithmeticException,NullPointerException,ArrayIndexOutOfBoundsException,NumberFormatException.
1. The top of the hierarchy is
Throwable. Both Error and Exception are its subclasses.2. Errors should NOT be handled (system-level problems).
3. Checked exceptions MUST be handled or declared. The compiler enforces this.
4. Unchecked exceptions (subclasses of RuntimeException) do NOT need to be handled or declared.
5. Common checked exceptions:
IOException, FileNotFoundException, SQLException.6. Common unchecked exceptions:
ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, NumberFormatException, ClassCastException.7. A very common exam question: “Which of the following is a checked exception?” Memorize the examples!
Question 5: Which of the following is a checked exception?
A) ArithmeticException B) NullPointerException C) IOException D) ArrayIndexOutOfBoundsException
Answer: C) IOException
IOException is a checked exception because it is a subclass of Exception but NOT a subclass of RuntimeException. The compiler requires you to handle or declare it. All the other options (ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException) are subclasses of RuntimeException, which makes them unchecked exceptions that the compiler does not force you to handle.
Question 6: Which of the following is an unchecked exception?
A) FileNotFoundException B) SQLException C) ClassNotFoundException D) NumberFormatException
Answer: D) NumberFormatException
NumberFormatException is a subclass of IllegalArgumentException, which is a subclass of RuntimeException. Since it inherits from RuntimeException, it is an unchecked exception. Options A, B, and C are all checked exceptions because they are subclasses of Exception but not of RuntimeException. The trick is to check whether the exception extends RuntimeException or not.
Question 7: The Java compiler forces you to handle or declare unchecked exceptions.
Answer: False
Only checked exceptions are enforced by the compiler. Unchecked exceptions (subclasses of RuntimeException) are not checked at compile time. You can choose to handle them or not, and the compiler will not complain either way. This is because unchecked exceptions typically represent programming mistakes that should be fixed in the code itself, rather than being handled at runtime.
The try-catch Block
Now let me teach you the most fundamental way to handle exceptions in Java: the try-catch block. This is the core of exception handling and you will use it in almost every program.
The idea is simple: you put the code that might cause an exception inside a try block, and you put the code that handles the exception inside a catch block. If an exception occurs in the try block, Java immediately stops executing the rest of the try block, jumps to the catch block, and executes the catch block code. If no exception occurs, the catch block is skipped entirely.
Syntax:
Let me rewrite our earlier division example with proper exception handling:
Output:
Do you see the difference? Earlier, the program crashed and the last line never ran. Now, the exception is caught in the catch block, a friendly error message is printed, and then the program continues to the next line and prints “Program ended normally.” This is the whole point of exception handling: catching the error so the program does not crash.
Let me explain the catch block parameters. ArithmeticException is the type of exception we are catching. The variable e is the exception object that Java created. Through this object, we can get information about the error. Some useful methods of the exception object are:
e.getMessage()– Returns a string describing the errore.toString()– Returns the exception name plus the messagee.printStackTrace()– Prints the full stack trace (exception name, message, and line numbers)
1. The
try block contains code that might throw an exception.2. The
catch block contains code that handles the exception.3. If an exception occurs in try, the remaining lines in try are skipped and control jumps to catch.
4. If no exception occurs, the catch block is completely skipped.
5. After try-catch, the program continues normally with the next statement.
6. A try block must be followed by at least one catch block or a finally block.
7. You cannot write a catch block without a try block.
8. The exception object
e has methods: getMessage(), toString(), printStackTrace().
Question 8: What happens to the statements in a try block that come AFTER the line where an exception occurs?
A) They execute normally B) They are skipped and control jumps to the catch block C) They execute after the catch block finishes D) They are moved to the finally block
Answer: B) They are skipped and control jumps to the catch block
When an exception occurs at a specific line inside the try block, Java immediately stops executing any remaining lines in that try block. Control jumps directly to the matching catch block. The skipped lines in the try block are NOT executed later, they are simply abandoned. This is important to remember for questions that ask about which lines execute and which do not.
Question 9: What will be the output of the following code?
Output:
Explanation: “Line 1” prints normally before the try block. Inside try, “Line 2” prints. Then 10 / 0 throws an ArithmeticException. “Line 3” is skipped because it comes after the exception line. Control jumps to the catch block, so “Line 4” prints. After the try-catch, “Line 5” prints. The key point is that “Line 3” never executes because it is in the try block after the exception.
Question 10: What will be the output if no exception occurs?
Output:
Explanation: Since 10 / 2 does NOT cause any exception (dividing by 2 is perfectly fine), all lines in the try block execute normally: “A” prints, the division happens, “B” prints. Because no exception occurred, the catch block is completely skipped. “C” does NOT print. After the try-catch, “D” prints. Remember: if no exception occurs, the catch block is ignored entirely.
Multiple Catch Blocks
Sometimes, the code inside a try block can throw more than one type of exception. In such cases, you can write multiple catch blocks, one for each type of exception. When an exception occurs, Java checks each catch block in order and executes the first one that matches the exception type.
Let me show you a practical example:
Output:
In this example, the first line in the try block causes a NumberFormatException. The remaining lines in the try block are skipped. Java checks the first catch block: is it NumberFormatException? Yes! So it executes that catch block and skips the other catch blocks. Only ONE catch block executes per exception, even if multiple catch blocks are written.
Important Rule: Order of Catch Blocks Matters
This is a very common exam question. Catch blocks must be ordered from most specific to most general. You cannot put a parent exception class before a child exception class. If you do, the compiler will give an error.
Why does Java enforce this? Because if the parent class catch comes first, it will catch ALL exceptions (including child class exceptions), making the child class catch block unreachable. Java detects this at compile time and gives an error. Always put the most specific (child) exception types first and the most general (parent) types last.
1. You can write multiple catch blocks after a single try block.
2. Only ONE catch block executes per exception (the first matching one).
3. Catch blocks must be ordered from most specific to most general (child to parent).
4. Putting a parent exception catch before a child exception catch causes a compile error (unreachable code).
5.
Exception is the parent class of most exceptions, so it should be the last catch block.6. After the first matching catch block runs, the remaining catch blocks are skipped.
Question 11: Which of the following multiple catch block arrangements will compile successfully?
A) catch(Exception e) then catch(ArithmeticException e) B) catch(ArithmeticException e) then catch(Exception e) C) catch(Throwable e) then catch(Exception e) D) catch(RuntimeException e) then catch(ArithmeticException e)
Answer: B) catch(ArithmeticException e) then catch(Exception e)
This is the only option where the child class comes before the parent class. ArithmeticException is a child of Exception, so this order is correct (specific first, general last). Options A, C, and D all put the parent class first, which makes the child class catch unreachable and causes a compile error. Remember the rule: always from most specific to most general.
Question 12: When multiple catch blocks are written, all matching catch blocks execute one after another.
Answer: False
Only the first catch block that matches the exception type will execute. After that catch block finishes, control passes to the code after the entire try-catch structure. The remaining catch blocks are completely skipped. Even if an exception matches two catch blocks (which can happen with parent-child relationships), only the first matching one runs.
The finally Block
The finally block is a special block that comes after the try-catch blocks. The code inside the finally block always executes, regardless of whether an exception occurred or not, and regardless of whether the exception was caught or not. Always. No exceptions. This makes it perfect for cleanup operations like closing files, closing database connections, or releasing resources.
Let me demonstrate with examples showing all possible scenarios:
Notice in Scenario 3 that even when the exception is NOT caught (wrong catch type), the finally block still runs BEFORE the program crashes. This demonstrates how reliable the finally block is.
There is one rare case where finally does NOT execute: if you call System.exit(0) inside the try block, which immediately terminates the entire JVM. Also, if the JVM itself crashes (like an OutOfMemoryError), finally might not run. But in normal circumstances, finally always runs.
You can also use try-finally WITHOUT a catch block:
1. The finally block always executes regardless of whether an exception occurred or was caught.
2. The finally block is used for cleanup operations (closing files, database connections, etc.).
3. A try block can have either catch or finally or both, but it cannot be alone.
4.
System.exit(0) is the only way to prevent finally from running in normal code.5. If both catch and finally modify a variable, the finally block’s value persists.
6. You can use try-finally without catch (but the exception will still crash the program after finally runs).
7. A very common exam question: “Does finally always execute?” The answer is YES, except for System.exit(0) or JVM crash.
Question 13: What will be the output?
Output:
Explanation: “Try” prints first. Then 10/0 throws ArithmeticException. Control jumps to catch, so “Catch” prints. Then the finally block runs, so “Finally” prints. After the entire try-catch-finally structure, “After” prints. All four lines print in order.
Question 14: What will be the output?
Output:
Explanation: “Try” prints. Since 10/2 does NOT cause any exception, the catch block is skipped. But the finally block still runs regardless, so “Finally” prints. Then “After” prints. Notice that “Catch” does NOT print because no exception occurred. The finally block runs even when there is no exception, which is its key characteristic.
Question 15: In which situation does the finally block NOT execute?
A) When an exception is caught B) When no exception occurs C) When System.exit(0) is called in the try block D) When the exception is not caught
Answer: C) When System.exit(0) is called in the try block
System.exit(0) immediately terminates the Java Virtual Machine. When the JVM shuts down, no more code runs, including the finally block. In all other scenarios (exception caught, no exception, exception not caught), the finally block runs. Options A, B, and D are all situations where finally DOES execute. Only System.exit(0) can prevent it.
The throw Keyword
So far, exceptions were thrown automatically by Java when something went wrong (like dividing by zero). But Java also allows you to manually throw an exception using the throw keyword. This is useful when you want to enforce certain rules in your code.
The syntax is simple:
Notice that we use new because we are creating a new exception object. Let me show you a practical example:
Output:
When we call setAge(-5), the condition age < 0 is true, so we manually throw an IllegalArgumentException with a descriptive message. The method stops executing at that point (the line this.age = age is never reached for the invalid input). The exception is caught in the main method's catch block.
1.
throw is used to manually throw an exception. It is used INSIDE a method or block.2. You must create a new exception object using
new: throw new ExceptionType("message").3. You can throw both checked and unchecked exceptions.
4. After
throw executes, the remaining code in that block is skipped.5.
throw (lowercase) is different from throws (lowercase with 's') - they do different things!6. Common use: validating input and throwing exceptions for invalid data.
Question 16: What is the correct syntax to manually throw an exception?
A) throw Exception("message") B) throw new Exception("message") C) throws new Exception("message") D) throw ExceptionType.message
Answer: B) throw new Exception("message")
You must use the new keyword to create an exception object because exceptions are objects in Java. The correct syntax is throw new ExceptionType("message"). Option A is wrong because it does not use new. Option C is wrong because throws is a different keyword used in method declarations, not for throwing exceptions. Option D is wrong syntax.
Question 17: What will be the output?
Output:
Explanation: check(10) passes the condition (10 is not negative), so "Value is: 10" prints. check(-5) fails the condition, so it throws RuntimeException. The line "Value is: -5" is skipped because throw stops execution. The exception is caught in the catch block, which prints "Negative value". check(20) never runs because control went to the catch block and then continues after the try-catch. So "Value is: 20" does NOT print.
The throws Keyword
Now let me explain the throws keyword. Notice the 's' at the end! This is different from throw. While throw actually throws an exception, throws is used in the method declaration to indicate that this method might throw certain exceptions. It is basically a warning sign on the method that says: "Calling this method might cause these exceptions, so be prepared to handle them."
The throws keyword is mainly used for checked exceptions. Remember, the compiler forces you to handle checked exceptions. If your method throws a checked exception and you do not catch it inside the method, you must declare it with throws. Otherwise, the code will not compile.
Let me show you a clear example:
Output:
In this example, FileInputStream constructor can throw a checked FileNotFoundException (which is a subclass of IOException). Since we do not catch this inside the readFile method, we must declare it with throws IOException. The caller of this method (main method) then handles it using try-catch.
You can declare multiple exceptions separated by commas:
What happens if you do NOT use throws for a checked exception?
The compiler gives an error because FileNotFoundException is a checked exception and you neither caught it nor declared it with throws. You have two choices: wrap it in try-catch, or declare it with throws.
1.
throws is used in the method declaration, not inside the method body.2.
throw is used inside a method to actually throw an exception.3.
throws is mainly used for checked exceptions (compiler enforces it).4. If a method throws a checked exception, you must either catch it inside the method or declare it with throws.
5. You can declare multiple exceptions:
throws IOException, SQLException.6. Using
throws does NOT handle the exception. It just passes the responsibility to the caller.7. The caller of a method with
throws must also handle or declare the exception.
Question 18: What is the purpose of the throws keyword in a method declaration?
A) To throw an exception inside the method B) To declare that the method might throw certain exceptions, passing handling responsibility to the caller C) To catch exceptions inside the method D) To execute cleanup code
Answer: B) To declare that the method might throw certain exceptions, passing handling responsibility to the caller
The throws keyword does NOT throw an exception (that is throw). It does NOT catch exceptions (that is catch). It does NOT execute cleanup code (that is finally). What throws does is declare in the method signature that this method might throw certain exceptions. It tells the caller: "You need to handle these exceptions when you call this method." The responsibility of handling is transferred to the caller.
Question 19: The throws keyword is used to handle a checked exception inside the method where it occurs.
Answer: False
The throws keyword does NOT handle the exception. It only declares that the method might throw certain exceptions. The actual handling must be done by the caller of the method using a try-catch block. If you want to handle the exception inside the method itself, you should use try-catch, not throws. This is a very important distinction that examiners test frequently.
Question 20: What will happen if a method throws a checked exception but does not declare it with throws and does not catch it with try-catch?
A) The exception is ignored B) Compile-time error C) Runtime error D) The exception is automatically handled
Answer: B) Compile-time error
For checked exceptions, the compiler enforces that you must either catch the exception (using try-catch) or declare it (using throws). If you do neither, the compiler will give an error saying "unhandled exception type." This compile-time checking is exactly why they are called "checked" exceptions. The compiler checks for them before the program can run.
Difference Between throw and throws
This comparison is asked very frequently in exams. Let me make it crystal clear.
| Feature | throw | throws |
|---|---|---|
| Purpose | Actually throws an exception | Declares that a method might throw exceptions |
| Where used | Inside a method or block | In the method declaration (signature) |
| What follows | An exception object: throw new Exception() | A list of exception classes: throws Exception1, Exception2 |
| Number | Throws ONE exception at a time | Can declare MULTIPLE exceptions |
| Effect on code | Stops execution of remaining code in the block | Does not stop execution; only a declaration |
| Checked vs Unchecked | Can throw both types | Mainly used for checked exceptions |
| Analogy | Actually pressing the alarm button | Putting a sign that says "alarm may ring" |
Question 21: The ________ keyword is used inside a method to actually throw an exception, while the ________ keyword is used in the method declaration to indicate possible exceptions.
Answer: throw, throws
throw (without 's') is the action keyword used inside a method body to create and throw an exception object. throws (with 's') is the declaration keyword used in the method signature to list the exceptions that the method might throw. Do not confuse these two! One common memory trick: "throw" is short because it does a small action. "throws" has an 's' because it lists multiple exception types.
Throwing Checked vs Unchecked Exceptions
There is an important difference in how Java treats manually thrown checked exceptions versus unchecked exceptions.
Throwing an unchecked exception: You can throw it anywhere without declaring it with throws.
Throwing a checked exception: You MUST either catch it or declare it with throws.
1. Throwing an unchecked exception (subclass of RuntimeException) does NOT require throws declaration.
2. Throwing a checked exception (subclass of Exception but not RuntimeException) REQUIRES either throws or try-catch.
3. If you are unsure whether an exception is checked or unchecked, check if it extends
RuntimeException.
User-Defined (Custom) Exceptions
Java has many built-in exception classes, but sometimes they are not enough to describe the specific errors in your application. For example, if you are writing a student management system, you might want an InvalidGradeException or an InsufficientFundsException. Java allows you to create your own exception classes. These are called user-defined exceptions or custom exceptions.
Creating a custom exception is very simple. You just create a class that extends one of the existing exception classes:
- For a checked custom exception: extend
Exception - For an unchecked custom exception: extend
RuntimeException
Now let me use this custom exception in a complete program:
Output:
See how we created a meaningful exception type that clearly describes the problem? Anyone reading this code understands exactly what kind of error can happen. This is much better than throwing a generic IllegalArgumentException.
If you want an unchecked custom exception, extend RuntimeException instead:
1. A custom exception is created by extending Exception (checked) or RuntimeException (unchecked).
2. You should provide at least a constructor that accepts a
String message and calls super(message).3. If your custom exception extends
Exception, you MUST use throws or try-catch when throwing it.4. If your custom exception extends
RuntimeException, no throws declaration is needed.5. Custom exceptions make your code more readable and meaningful.
6. The exam often asks you to write a complete custom exception class and use it in a program. Practice this!
Question 22: How do you create a custom checked exception?
A) Implement the Exception interface B) Extend the RuntimeException class C) Extend the Exception class D) Use the custom keyword
Answer: C) Extend the Exception class
To create a checked custom exception, you extend the Exception class. If you extended RuntimeException, it would be an unchecked exception (option B is wrong). There is no "Exception interface" to implement (option A is wrong). There is no "custom" keyword in Java (option D is wrong). The standard way is: class MyException extends Exception { }
Question 23: Write a custom exception class called InsufficientBalanceException that extends Exception and has a constructor accepting a message. Then write a BankAccount class with a withdraw method that throws this exception if the withdrawal amount exceeds the balance.
Output:
Nested try Blocks
Java allows you to put a try block inside another try block. This is called nested try blocks. You use this when different parts of your code need different levels of exception handling.
Output:
The rule is: if an exception occurs in the inner try block, the inner catch blocks are checked first. If none of them match, the exception propagates to the outer try block and the outer catch blocks are checked. This propagation continues outward until a matching catch is found or the program crashes.
Question 24: What will be the output?
Output:
Explanation: "Outer try" prints. Then "Inner try" prints. The division by zero throws ArithmeticException. The inner catch matches, so "Inner catch" prints. After the inner try-catch finishes, "After inner try-catch" prints (back in the outer try). No exception occurs in the outer try at this point, so "Outer catch" is skipped. "End" prints. The inner catch handled the exception, so it never reached the outer catch.
Common Exception Classes in Java
Let me list the most common exception classes that you need to know for your exam. I will explain what each one means and when it occurs.
| Exception Class | Type | When It Occurs |
|---|---|---|
ArithmeticException | Unchecked | Illegal arithmetic operation like dividing by zero |
NullPointerException | Unchecked | Trying to use a reference variable that points to null |
ArrayIndexOutOfBoundsException | Unchecked | Accessing an array with an invalid index |
NumberFormatException | Unchecked | Trying to convert a non-numeric string to a number |
ClassCastException | Unchecked | Trying to cast an object to an incompatible type |
StringIndexOutOfBoundsException | Unchecked | Accessing a character in a String with an invalid index |
StackOverflowError | Error | Method calls itself infinitely (infinite recursion) |
OutOfMemoryError | Error | JVM runs out of memory |
IOException | Checked | General I/O failure (file operations, network) |
FileNotFoundException | Checked | Trying to access a file that does not exist |
SQLException | Checked | Database access error |
InterruptedException | Checked | A thread is interrupted while waiting/sleeping |
Question 25: Which exception occurs when you try to call a method on a null reference variable?
A) ArithmeticException B) NumberFormatException C) NullPointerException D) ClassCastException
Answer: C) NullPointerException
NullPointerException occurs when you try to use an object reference that is null. For example, if you write String s = null; and then s.length(), Java throws NullPointerException because s does not point to any actual String object. This is one of the most common runtime exceptions in Java programs.
Question 26: Which exception occurs when Integer.parseInt("abc") is executed?
A) ArithmeticException B) NullPointerException C) NumberFormatException D) IOException
Answer: C) NumberFormatException
Integer.parseInt("abc") tries to convert the string "abc" to an integer. Since "abc" is not a valid number, Java throws a NumberFormatException. This is a subclass of IllegalArgumentException, which is a subclass of RuntimeException, making it an unchecked exception. If the string were "123", it would convert successfully without any exception.
Exception Propagation
Exception propagation (also called exception bubbling) is the process by which an exception moves up through the call stack when it is not caught in the current method. Let me explain this clearly.
When an exception occurs in a method and the method does not catch it, the exception is not lost. Instead, Java automatically passes (propagates) the exception to the method that called this method. If that method also does not catch it, it propagates further up, and so on, until it reaches the main method. If even main does not catch it, the JVM terminates the program and prints the error.
For unchecked exceptions, this propagation happens automatically. For checked exceptions, the compiler forces you to either catch or declare at each level.
Output:
The stack trace shows the full propagation path: the exception started at methodC (line 3), propagated to methodB (line 8), then to methodA (line 13), then to main (line 18). None of the "This never prints" lines executed because the exception kept propagating upward.
Now if we catch the exception at any level, the propagation stops there:
Output:
The propagation stopped at methodA because that is where we caught it. The program continues normally from there.
1. Exception propagation is the process of an exception moving up the call stack when not caught.
2. Unchecked exceptions propagate automatically.
3. Checked exceptions must be declared with throws at each level of propagation.
4. Propagation stops when a catch block matches the exception type.
5. If the exception reaches
main() and is not caught, the JVM terminates the program.6. The stack trace shows the exact path of propagation from the origin to the top.
Question 27: Where does an unchecked exception propagate if it is not caught in the method where it occurred?
A) It is silently ignored B) It automatically propagates to the caller method C) It is stored in a buffer D) It is converted to a checked exception
Answer: B) It automatically propagates to the caller method
When an unchecked exception is not caught in the current method, Java automatically passes it up to the method that called the current method. This continues up the call stack until either a matching catch block is found or the exception reaches the main method and causes the JVM to terminate. The programmer does not need to write any special code for this propagation; it happens automatically for unchecked exceptions.
Exercises with Answers
Integer.parseInt(). Handle the NumberFormatException that occurs if the string is not a valid number. Also handle any other unexpected exceptions using a general Exception catch block. Use a finally block to print a completion message.
Output (with "Hello World"):
Output (with "123"):
divide(int a, int b) that throws an ArithmeticException if b is zero. Call this method from main with different values and handle the exception. Also show what happens when no exception occurs.
Output:
InvalidEmailException. Write a method validateEmail(String email) that throws this exception if the email does not contain "@" or does not contain ".". Write a main method to test with both valid and invalid emails.
Output:
Errors found:
Error 1: The throws IOException is written inside the method body. The throws clause must be in the method declaration (in the method signature), not inside the method body. Also, import java.io.IOException; is missing.
Error 2: There are duplicate catch blocks for IOException. You cannot have two catch blocks for the same exception type. The second catch (IOException e) block is unreachable and causes a compile error.
Corrected code:
More Practice Questions for Exam
Question 28: What will be the output?
Output:
Explanation: "A" prints. Division by zero throws ArithmeticException in the inner try. "B" prints in the inner catch. Then inside that catch, arr[5] throws ArrayIndexOutOfBoundsException. The inner catch does not catch this, so it propagates out of the inner try-catch-finally. But first, the inner finally runs and prints "C". Then the ArrayIndexOutOfBoundsException reaches the outer try-catch, and the outer catch matches, printing "D". After the outer try-catch, "E" prints. Key insight: the finally block of the inner try runs even when an exception occurs inside the catch block.
Question 29: What will be the output?
Output:
Explanation: Inside the try block, x is set to 10, then return is encountered. Normally, return would immediately exit the method. But the finally block MUST run before the method actually returns. So the finally block executes, setting x to 30 and printing "x = 30". After the finally block, the method returns (the original return is completed). The "After finally" line does NOT print because the method already has a return statement in the try block. The finally block runs even when there is a return in the try block!
Question 30: Explain the complete exception hierarchy in Java with a diagram. List at least two examples for each category (Error, Checked Exception, Unchecked Exception).
Answer:
Error examples: OutOfMemoryError, StackOverflowError. These are serious system problems that should not be handled.
Checked Exception examples: IOException, FileNotFoundException, SQLException, ClassNotFoundException. The compiler forces handling.
Unchecked Exception examples: ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, NumberFormatException, ClassCastException. The compiler does not force handling.
Question 31: List the five keywords used in Java exception handling and explain each with one sentence.
Answer:
1. try: A block that contains code that might throw an exception; if an exception occurs, control jumps to catch.
2. catch: A block that catches and handles a specific type of exception thrown by the try block.
3. finally: A block that always executes after try-catch, regardless of whether an exception occurred or was caught, used for cleanup.
4. throw: A keyword used inside a method to manually throw an exception object.
5. throws: A keyword used in a method declaration to declare that the method might throw certain checked exceptions.
Question 32: What will be the output?
Output:
Explanation: The exception originates in m1, propagates to m2 (which declares throws), then propagates to m3 (which also declares throws), then propagates to main where it is finally caught by the catch block. Since all methods properly declared the checked exception with throws, the code compiles. The catch block prints the message "From m1" which was set when the exception was created. The propagation path is m1 -> m2 -> m3 -> main, and it stops at main because that is where the catch block is.
1. Memorize the five keywords: try, catch, finally, throw, throws. Know exactly what each one does.
2. Memorize the exception hierarchy: Throwable -> Error and Exception -> RuntimeException (unchecked) and others (checked).
3. Know which exceptions are checked (IOException, FileNotFoundException, SQLException) and which are unchecked (ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, NumberFormatException).
4. Remember: catch blocks go from most specific to most general (child to parent). Parent first = compile error.
5. The finally block always executes (except System.exit(0)). Even with return in try, finally runs first.
6. After an exception in try, remaining try lines are skipped. Only ONE catch block executes.
7.
throw = inside method, throws one exception. throws = in method declaration, lists possible exceptions.8. Custom exception: extend
Exception for checked, extend RuntimeException for unchecked. Always call super(message).9. Exception propagation: unchecked propagates automatically, checked must be declared with throws at each level.
10. Practice "find the output" questions with nested try-catch-finally. These are very common in exams.
11. Remember the useful exception object methods:
getMessage(), toString(), printStackTrace().12. When writing custom exceptions, always include a constructor that accepts a String message parameter.