What is Exception?
Exceptions are unexpected events that disrupt the normal flow of program execution.
While some can be handled programmatically, critical errors such as system-level failures can impact application stability.
In Java, an exception is an object derived from the Throwable
superclass.
When an exception occurs during program execution, the runtime system generates a stack trace ,a structured report that provides valuable diagnostic information to help developers locate and fix the problem.
A typical stack trace includes the following key elements:
Type of Exception
The stack trace specifies the type of exception thrown, typically a class name from the programming language’s exception hierarchy.
For example: java.lang.ArithmeticException: / by zero
indicates that an ArithmeticException
occurred because the code attempted to divide a number by zero, which is not allowed.
Call Stack Method
The stack trace shows the sequence of method calls active when the exception occurred, known as the call stack. It traces the program’s execution path starting from the method where the exception was thrown and moving backward through the calling methods.
Class and Method Names
Each line in the stack trace includes the fully qualified name of the class and method where the exception occurred.
Example: at com.example.math.Calculator.divide(Calculator.java:25)
indicates the exception was thrown in the divide
method of the Calculator
class within the com.example.math
package.
File Names and Line Numbers
Most stack traces also show the source file name and the exact line number where the exception occurred. This is especially useful for debugging, as it allows developers to pinpoint the exact location of the error.
Example: The issue in the example above happened at line 25 of the Calculator.java
file.
In Java, exceptions are unexpected events that disrupt the normal flow of a program. They often arise from situations that the program cannot handle on its own. Some of the most common causes of exceptions include:
Invalid User Input
One frequent cause is improper or unexpected input from users.
Examples include entering a string when a number is expected, providing an empty value where input is required, or submitting data that violates business rules.
Missing Files
Applications that read from or write to files may encounter exceptions if a file is missing or inaccessible.
This can be caused by the file not existing or having an incorrect path, lack of permission to access the file, or the file being used by another process.
Network Failures or Other Runtime Anomalies
Programs that rely on network communication can experience exceptions due to unpredictable events.
Common causes include internet disconnection, server timeouts, or receiving corrupt or malformed data from a server.
The Throwable Class Hierarchy
At the root of Java's exception hierarchy is the Throwable
class, which has two main branches: Error
and Exception
.
Examples of errors include InternalError
, OutOfMemoryError
, and AssertionError
.
Examples of exceptions include IOException
and RuntimeException
.
See: Throwable API Documentation
Types of Exceptions
Exceptions in Java fall into two categories: built-in and user-defined.
Built-in Exceptions
Built-in exceptions are provided by Java libraries and can be
classified as checked
or unchecked
exceptions.
-
Checked exceptions: must be either caught or declared in the method signature.
They are typically conditions that a program should recover from, such as
IOException
,SQLException
. -
Unchecked exceptions: occur at runtime and are usually due to programming errors, such as
NullPointerException
,ArithmeticException
.
User-defined Exceptions
User-defined exceptions are custom exceptions which are created by programmers to handle application-specific scenarios and are helpful for debugging and edge-case handling.
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class TestCustomException {
static void validate(int age) throws CustomException {
if (age < 20) {
throw new CustomException("Age is not valid for our purpose");
} else {
System.out.println("It is good");
}
}
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("Enter age:");
int age = sc.nextInt();
validate(age);
} catch (CustomException ex) {
System.err.println("Exception occurred: " + ex);
}
}
}
Exception Handling
In real-world applications, errors are inevitable due to invalid inputs, hardware failures, or unpredictable runtime conditions. Without proper handling, these can lead to application crashes and data loss.
Java provides a robust mechanism for handling such errors using try-catch
blocks, the throw
and throws
keywords, and custom exception classes.
This approach ensures smoother execution and better user experience by gracefully managing runtime anomalies.
Use try-catch
blocks to catch and resolve exceptions.
To explicitly create an exception while a program is running, use the throw keyword. The software searches for a specific piece of code known as an exception handler to handle the error when an exception is thrown, disrupting the program's normal flow.
Syntax: throw new ExceptionType("Error message");
public class ThrowKeyword {
public static void checkAge(int age) {
if (age <16) {
throw new IllegalArgumentException("Age must be greater than 16.");
}
System.out.println("Age is: " + age);
}
public static void main(String[] args) {
try {
checkAge(10); // will throw an exception
} catch (IllegalArgumentException e) {
System.out.println("Exception: " + e.getMessage());
}
checkAge(6); // This call will not throw an exception
}
}
The throws
keyword is used in method declarations to indicate that a method may throw certain exceptions.
The caller must handle these using a try-catch
block.
Syntax: type method_name(parameters) throws exception_list
Note: The exception_list used in a program can either be predefined by Java (built-in exceptions) or defined by the programmer (custom exceptions) to handle specific situations.
static void validate(int age) throws CustomException {
if(age < 18) {
throw new CustomException("The age is invalid");
}
}
The finally Block in Java
A key component of Java's exception-handling mechanism is the finally block. It defines a section of code that always executes, regardless of whether an exception is thrown or caught. This makes it particularly useful for performing essential cleanup operations, such as closing files or releasing resources.
Main features include:
- Although optional, the
finally
block must appear after atry
orcatch
block. - The code inside the
finally
block executes even if no exception occurs. - The only exceptions to this behavior are when the program is forcibly terminated or the JVM exits (e.g., via
System.exit()
).
public class SimpleFinallyBlock {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
int first = sc.nextInt();
int second = sc.nextInt();
int result = divide(first, second);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.err.println("Exception: " + e);
} finally {
System.out.println("Good Bye!!");
}
}
public static int divide(int a, int b) {
return a / b;
}
}