Error vs Exception - Yash-777/MyWorld GitHub Wiki
public class Throwable implements Serializable gitlink
| Diagram | Exception Hierarchy |
|---|---|
|
An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.
Throwable
βββ Error (unchecked)
β βββ OutOfMemoryError
β βββ StackOverflowError
β βββ java.lang.Error: Unresolved compilation problem
β βββ ...
βββ Exception
βββ RuntimeException (unchecked) - No compile-time error
β βββ NullPointerException
β βββ ArrayIndexOutOfBoundsException
β βββ IllegalArgumentException
β βββ ...
βββ Checked Exceptions - Must be handled (try-catch or throws)
βββ IOException
βββ SQLException
βββ ClassNotFoundException
βββ ...
|
| Error | Checked Exceptions | Un-Checked Exceptions (RuntimeException) No compile-time error |
|---|---|---|
public static void triggerUnrecoverableError() {
System.out.println("Method: Throwing a System Error.");
throw new Error("Critical Failure: The system cannot continue.");
}
public static void causeError() {
System.out.println("Throwing Error...");
throw new StackOverflowError("Serious JVM Error");
}
public static void demonstrateErrorWithThrows() throws Error {
System.out.println("Method: Error with throws declaration");
throw new Error("Critical system error");
}
public static void demonstrateErrorNoThrows() {
System.out.println("Method: Error without throws (not required)");
throw new Error("Critical system error");
} |
public static void causeCheckedException() throws MyCheckedException {
System.out.println("Throwing Checked Exception...");
throw new MyCheckedException("Custom Checked Exception Occurred");
}
public static void demonstrateCheckedExceptionWithThrows() throws MyCheckedException {
System.out.println("Method: Checked exception with throws declaration");
throw new MyCheckedException("Custom checked exception");
}class MyCheckedException extends Exception {
public MyCheckedException(String message) {
super(message);
}
} |
public static void demonstrateUncheckedExceptionNoHandling() {
System.out.println("Method: RuntimeException without handling");
throw new RuntimeException("Runtime error occurred");
}
public static void demonstrateUncheckedExceptionWithTryCatch() {
System.out.println("Method: RuntimeException with try-catch");
try {
throw new RuntimeException("Runtime error occurred");
} catch (RuntimeException e) {
System.out.println("Caught: " + e.getMessage());
}
System.out.println("Execution continues after catch");
}
public static int getLength(String s) {
if (s == null) {
System.out.println("Throwing Runtime Exception...");
throw new IllegalArgumentException("The argument cannot be null");
}
return s.length();
} |
Error Behavior with Threads
| Error can be caught using catch, but it is not recommended. Errors represent serious problems. You can catch them to prevent abnormal thread termination, but generally applications are not expected to recover from them. |
If an Error is not caught, the current thread terminates β but the finally block still executes. Even when an Error occurs, the finally block runs (unless the JVM itself crashes). After that, the current thread stops, but other threads continue running normally. |
Thread Isolation: Each thread runs independently. An Error in one thread usually affects only that particular thread, not the entire application. Other request threads keep processing. |
|---|---|---|
|
Error CAN be caught to prevent thread termination β
Result: Thread survives, continues execution // Example 1: StackOverflowError with finally
public static void demonstrateStackOverflowErrorWithFinally() {
System.out.println("--- StackOverflowError Test ---");
try {
System.out.println("Before causing StackOverflowError");
causeStackOverflow(0);
System.out.println("After error (won't print)");
} catch (StackOverflowError e) {
System.out.println("Caught StackOverflowError");
} finally {
System.out.println("β Finally block EXECUTED despite StackOverflowError");
}
System.out.println("Program continues after finally\n");
}
// Example 2: Simulated OutOfMemoryError with finally
public static void demonstrateOutOfMemoryErrorWithFinally() {
System.out.println("--- Custom Error Test ---");
try {
System.out.println("Before throwing Error");
throw new OutOfMemoryError("Simulated memory error");
} catch (OutOfMemoryError e) {
System.out.println("Caught OutOfMemoryError: " + e.getMessage());
} finally {
System.out.println("β Finally block EXECUTED despite OutOfMemoryError");
}
System.out.println("Program continues after finally\n");
}
|
Error with Finally (NOT caught) = Thread dies BUT finally executes β
Result: Finally runs β Thread terminates β Other threads continue public static void demonstrateErrorWithFinallyNoCatch() {
System.out.println("--- Error without Catch Test ---");
try {
System.out.println("Before throwing Error");
throw new Error("Generic error");
} finally {
System.out.println("β Finally block EXECUTED even without catch block");
}
// Program terminates after finally
}
Real Server Example (Simplified Servlet)public class ServletRequestHandler {
public void handleHttpRequest(HttpRequest request) {
String threadName = Thread.currentThread().getName();
Connection dbConnection = null;
try {
System.out.println("[" + threadName + "] Processing request: " + request.getUrl());
dbConnection = getDbConnection();
// User's buggy code might cause StackOverflowError
String result = processUserRequest(request);
sendResponse(result);
} catch (Exception e) {
System.err.println("[" + threadName + "] Exception: " + e.getMessage());
sendErrorResponse(500);
} finally {
// β This executes even if StackOverflowError occurs
if (dbConnection != null) {
dbConnection.close(); // Resource cleanup happens
System.out.println("[" + threadName + "] β DB connection closed");
}
System.out.println("[" + threadName + "] Request completed (thread ending)");
}
// If Error occurred, thread dies here but server continues
// Other request threads keep processing
}
}
|
Thread Isolation: Error kills ONLY that thread β
Result: Thread-2 dies, Thread-1 and Thread-3 continue β Thread t1 = new Thread(() -> {
System.out.println("Thread-1: Working...");
// No error - completes normally
});
Thread t2 = new Thread(() -> {
System.out.println("Thread-2: Working...");
throw new StackOverflowError(); // Dies here
});
Thread t3 = new Thread(() -> {
System.out.println("Thread-3: Working...");
// No error - completes normally
});
t1.start();
t2.start(); // β Only this thread dies
t3.start();
Server with Multiple Request Threadspublic class ErrorThreadBehavior {
public static void main(String[] args) {
System.out.println("=== Server Simulation: Multiple Request Threads ===\n");
// Simulate 5 concurrent user requests
Thread request1 = new Thread(() -> handleRequest("User-1", false), "Request-Thread-1");
Thread request2 = new Thread(() -> handleRequest("User-2", true), "Request-Thread-2"); // Will throw StackOverflowError
Thread request3 = new Thread(() -> handleRequest("User-3", false), "Request-Thread-3");
Thread request4 = new Thread(() -> handleRequest("User-4", false), "Request-Thread-4");
// Start all threads
request1.start();
request2.start();
request3.start();
request4.start();
// Main thread continues
System.out.println("[MAIN] Server main thread continues running...\n");
// Wait for all threads to complete
try {
request1.join();
request2.join(); // This will finish (abnormally)
request3.join();
request4.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\n[MAIN] All request threads completed. Server still running!");
}
public static void handleRequest(String user, boolean causeError) {
String threadName = Thread.currentThread().getName();
System.out.println("[" + threadName + "] Processing request for " + user);
try {
Thread.sleep(100); // Simulate processing time
if (causeError) {
System.out.println("[" + threadName + "] Triggering StackOverflowError...");
causeStackOverflow(); // This will kill only this thread
}
System.out.println("[" + threadName + "] β Successfully processed request for " + user);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Recursive method to cause StackOverflowError
public static void causeStackOverflow() {
causeStackOverflow(); // Infinite recursion
}
} |
In Java, throwing exceptions is a specific programming technique. An exception can only be caught if it was thrown before, either by the Java platform (JVM) or by custom code using the throw statement.
The throw Statement - Actually Throws an Exception/Error |
The throws Statement - Declares Potential Exceptions/Errors |
|---|---|
// With Error
public void simulateCrash() {
throw new OutOfMemoryError("Memory exhausted");
}
// With Checked Exception
public void readData() {
throw new IOException("File not found");
}
// With Exception
public void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
}
|
// Error - throws OPTIONAL
public void crash() throws Error { // Optional
throw new Error("System crash");
}
// Checked Exception - throws REQUIRED
public void readFile() throws IOException {
throw new IOException("Read error");
}
// Unchecked Exception - throws OPTIONAL
public void divide() throws ArithmeticException { // Optional
throw new ArithmeticException("Divide by zero");
}
|
Error Class (Cannot handled by the program): When a dynamic linking failure or other hard failure in the Java virtual machine occurs, the virtual machine throws an Error. Simple programs typically do not catch or throw Errors.
Exception Class (can be handled by the program): Most programs throw and catch objects that derive from the Exception class. An Exception indicates that a problem occurred, but it is not a serious system problem. Most programs you write will throw and catch Exceptions as opposed to Errors.
What is the difference between exception and error in Java?
Errors typically happen while an application is running. For instance, Out of Memory Error occurs in case the JVM runs out of memory. On the other hand, exceptions are mainly caused by the application. For instance, Null Pointer Exception happens when an app tries to get through a null object.
Exceptions docs.oracle.com
An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.
Java exception is an unusual condition that generally occurs in a code sequence while the program is being executed. And, when an exception occurs in your code, it completely disrupts the normal flow of the program and abnormally terminates the process, so it must be handled correctly.
The term exception is shorthand for the phrase "exceptional event."
When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.
After a method throws an exception, the runtime system attempts to find something to handle it. The set of possible "somethings" to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred. The list of methods is known as the call stack

The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.
The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, as shown in the next figure, the runtime system (and, consequently, the program) terminates.

Using exceptions to manage errors has some advantages over traditional error-management techniques. You can learn more in the Advantages of Exceptions section.
Exception handling is the process of responding to unwanted or unexpected events when a computer program runs. Exception handling deals with these events to avoid the program or system crashing, and without this process, exceptions would disrupt the normal operation of a program.
How do you handle exceptions in Java?
Exception handling can be performed using try, catch, and finally blocks
Try blocks should include code that might throw an exception. If your code throws more than one exception, you can choose whether to:
- Use a separate try block for every statement that may throw an exception or
- Use one try block for several statements that could throw multiple exceptions.
Each Catch block should handle exceptions thrown by the try blocks. The finally block gets executed whether or not an exception is thrown after the successful execution of the try block or after one of the catch blocks.
There is no limit to add catch blocks, as you can include as many Catch blocks as you want. However, you can add only one finally block to each try block.
The runtime system always executes the statements within the finally block regardless of what happens within the try block. So it's the perfect place to perform cleanup.
try {
} catch (IndexOutOfBoundsException e) { // catch (ExceptionType name)
System.err.println("IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
}Note: The finally block may not execute if the JVM exits while the try or catch code is being executed.
Types of Exceptions in Java
Generally, there are two kinds of Java exceptions, namely:
Checked exceptions (compile-time exceptions): compiler checks whether the exception is handled and throws an error accordingly. Unchecked exceptions (runtime exceptions): Occur during program execution. These are not detectable during the compilation process.
Checked exceptions. Also called compile-time exceptions, the compiler checks these exceptions during the compilation process to confirm if the exception is being handled by the programmer. If not, then a compilation error displays on the system.
The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions
Some of the most common Checked exceptions in Java include:
class IOException extends Exception [CharConversionException, EOFException, FileNotFoundException, SSLException,
ObjectStreamException, ObjectStreamException]
ParseException, InterruptedException, InvocationTargetException, NoSuchMethodException, SQLException, ClassNotFoundException.
- IOException: Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
- SOAPException
Unchecked exceptions. Also called runtime exceptions, these exceptions occur during program execution. These exceptions are not checked at compile time, so the programmer is responsible for handling these exceptions. Unchecked exceptions do not give compilation errors.
RuntimeException and its subclasses are unchecked exceptions. class RuntimeException extends Exception
Some of the most common Unchecked exceptions in Java include:
class ArithmeticException extends RuntimeException
class IndexOutOfBoundsException extends RuntimeException [ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException]
NumberFormatException, ArithmeticException, ClassCastException, IllegalArgumentException, IllegalStateException
- NullPointerException: Thrown when an application attempts to use null in a case where an object is required.
- ArithmeticException: Thrown when an exceptional arithmetic condition has occurred. When any integet/number is "divide by zero" throws an instance of this class.
- IndexOutOfBoundsException: Thrown to indicate that an index of some sort (such as to an array, to a string, or to a vector) is out of range.
- ClassCastException, ConcurrentModificationException, FileSystemNotFoundException, NoSuchElementException, UnsupportedOperationException, UnmodifiableSetException, DOMException
Why do we need exception handling in Java?
If there is no try and catch block while an exception occurs, the program will terminate. Exception handling ensures the smooth running of a program without program termination.
Throwing exceptions
In Java, throwing exceptions is a specific programming technique. An exception can only be caught if it was thrown before, either by the Java platform or by custom code. In Java, exceptions are thrown with the throw statement. For example, ArrayIndexOutOfBoundsException, NullPointerException, and IOException were all thrown automatically by the Java platform.
- The Throw Statement
Throwable objects that inherit from the Throwable class can be used with the throw statement. Any block of code explicitly throws an exception. A catch block must follow each throw statement inside a try block.
- The Throws Statement
Java has a throws statement in addition to a throw. Any method that might throw a checked exception can use it in its signature. As an example, letβs say that the method doesnβt want to and cannot handle a checked exception that will prevent the code from compiling. With the throws keyword, you can indicate that the caller needs to handle this exception in its own try-catch block.
Handling NullPointerException?
NullPointerExceptionseagence.com blog is a kind of Runtime exception that occurs when you try to access a variable that doesnβt point to any object and refers to nothing or null.
Following are the most common situations for the java null pointer exception occurrence.
- When null parameters are passed on to a method.
- Trying to access the properties or an index element of a null object.
- Calling methods on a null object.
String str = null;str.length();if ("Yash".equals(str)) - Following incorrect configuration for dependency injection frameworks such as Spring.
public static int getLength(String s) {
if (s == null)
throw new IllegalArgumentException("The argument cannot be null");
return s.length();
}