Exceptions in Java are events that occur during program execution and disrupt the normal flow of a program. Java provides many built-in exceptions to handle common runtime and compile-time errors. Developers can also create custom exceptions to handle application-specific error conditions.
- Exceptions help detect and handle errors gracefully.
- Java provides both built-in and user-defined exceptions.
- Proper exception handling improves program reliability and maintainability.

- Checked Exceptions: Checked by the compiler and must be caught or declared using throws. Examples include IOException and ClassNotFoundException.
- Unchecked Exceptions: Subclasses of RuntimeException that do not require explicit handling or declaration. Examples include NullPointerException and NumberFormatException.
Built-in Exceptions
Built-in exceptions are predefined exception classes provided by Java's standard library to handle common runtime and compile-time errors. They help identify and manage abnormal situations such as invalid input, file errors, arithmetic errors, and null references. Java automatically throws these exceptions when such conditions occur.
- Built-in exceptions are predefined and available in Java libraries.
- They help handle common errors and prevent unexpected program termination.
Examples of Built-in Exception
1. ArithmeticException
ArithmeticException is thrown when an exceptional arithmetic condition occurs, such as attempting to divide an integer by zero.
class ArithmeticException_Demo
{
public static void main(String args[])
{
try {
int a = 30, b = 0;
int c = a/b; // cannot divide by zero
System.out.println ("Result = " + c);
}
catch(ArithmeticException e) {
System.out.println ("Can't divide a number by 0");
}
}
}
Output
Can't divide a number by 0
Explanation: Integer division by zero throws ArithmeticException. The catch block handles the exception and displays an appropriate message.
2. NullPointerException
NullPointerException occurs when a program attempts to use a null reference where an object is required, such as calling an instance method on it.
class GFG {
public static void main(String[] args)
{
try {
String name = null;
System.out.println(name.length());
}
catch (NullPointerException e) {
System.out.println("Object reference is null");
}
}
}
Output
Object reference is null
Explanation: The name variable contains null. Calling length() on it throws NullPointerException. In practice, validate references and design APIs to avoid unexpected null values rather than relying on catching this exception during normal processing.
3. StringIndexOutOfBoundsException
StringIndexOutOfBoundsException occurs when an invalid index is used to access characters in a string.
- Happens when index is less than 0 or greater than string length.
- Thrown by String class methods.
class GFG {
public static void main(String[] args)
{
try {
String text = "Java";
char ch = text.charAt(5);
System.out.println(ch);
}
catch (StringIndexOutOfBoundsException e) {
System.out.println("Invalid string index");
}
}
}
Output
Invalid string index
Explanation: The string "Java" has four characters, with valid indices from 0 to 3. Accessing index 5 throws StringIndexOutOfBoundsException.
4. ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException occurs when a program attempts to access an array using an index that is negative or greater than or equal to its length.
class GFG {
public static void main(String[] args)
{
try {
int[] numbers = { 10, 20, 30 };
System.out.println(numbers[5]);
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println(
"Array index is out of bounds");
}
}
}
Output
Array index is out of bounds
Explanation: The array has three elements, with valid indices 0, 1, and 2. Accessing index 5 throws ArrayIndexOutOfBoundsException.
Note: The correct Java exception name is ArrayIndexOutOfBoundsException, not ArrayOutOfBoundException.
5. NumberFormatException
NumberFormatException occurs when an application tries to convert a string into a numeric type but the string does not have a valid representation for that type.
class GFG {
public static void main(String[] args)
{
try {
String value = "abc";
int number = Integer.parseInt(value);
System.out.println(number);
}
catch (NumberFormatException e) {
System.out.println("Invalid number format");
}
}
}
Output
Invalid number format
Explanation: The string "abc" cannot be converted into an integer, so Integer.parseInt() throws NumberFormatException.
6. FileNotFoundException
FileNotFoundException is a checked exception that can occur when an application attempts to open a file that does not exist or cannot be opened for the requested operation.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
class File_notFound_Demo {
public static void main(String args[]) {
try {
// Following file does not exist
File file = new File("E://file.txt");
FileReader fr = new FileReader(file);
} catch (FileNotFoundException e) {
System.out.println("File does not exist");
}
}
}
Output
File does not exist
Explanation: The constructor attempts to open the specified file. If it does not exist, FileNotFoundException is thrown. Try-with-resources automatically closes the reader when it has been opened successfully.
7. IOException
IOException represents failures during input/output operations, such as reading a file, writing data, or communicating through streams.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
class GFG {
public static void main(String[] args)
{
try {
String content
= Files.readString(Path.of("data.txt"));
System.out.println(content);
}
catch (IOException e) {
System.out.println("Unable to read the file");
}
}
}
Output
Unable to read the file
Explanation: Files.readString() may throw IOException if the file cannot be read. The catch block handles the failure. Unlike the original example using Scanner.ioException(), this code demonstrates an actual I/O exception-handling scenario.
8. NoSuchMethodException
NoSuchMethodException is a checked exception that occurs when reflection attempts to retrieve a method that cannot be found.
class GFG {
public static void main(String[] args)
{
try {
Class<?> cls = String.class;
cls.getMethod("unknownMethod");
}
catch (NoSuchMethodException e) {
System.out.println("Method not found");
}
}
}
Output
Method not found
Explanation: The String class does not contain a public, zero-argument method named unknownMethod. Therefore, getMethod() throws NoSuchMethodException. This is different from NoSuchElementException, which can occur when attempting to retrieve an element from an empty iterator.
9. IllegalArgumentException
IllegalArgumentException occurs when a method receives an argument that violates its requirements.
class GFG {
static void setAge(int age)
{
if (age < 0) {
throw new IllegalArgumentException(
"Age cannot be negative");
}
System.out.println("Age: " + age);
}
public static void main(String[] args)
{
try {
setAge(-5);
}
catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}
Output
Age cannot be negative
Explanation: The setAge() method requires a non-negative age. Passing -5 violates this condition, so the method throws IllegalArgumentException.
10. IllegalStateException
IllegalStateException occurs when a method is invoked while an object is in a state that does not permit the requested operation.
class GFG {
private boolean connected = false;
void sendData()
{
if (!connected) {
throw new IllegalStateException(
"Connection is not established");
}
System.out.println("Data sent");
}
public static void main(String[] args)
{
GFG obj = new GFG();
try {
obj.sendData();
}
catch (IllegalStateException e) {
System.out.println(e.getMessage());
}
}
}
Output
Connection is not established
Explanation: The object is not connected when sendData() is called. Because the operation requires an established connection, the method throws IllegalStateException.
11. ClassNotFoundException
ClassNotFoundException is a checked exception thrown when an application tries to load a class dynamically but the requested class cannot be found.
class GFG {
public static void main(String[] args) {
try {
Class.forName("UnknownClass");
} catch (ClassNotFoundException e) {
System.out.println("Class not found");
}
}
}
Output
Class not found
Explanation: Class.forName() attempts to locate and load the specified class. If the class cannot be found, it throws ClassNotFoundException.
StackOverflowError in Java
StackOverflowError occurs when a thread's call stack exceeds its available capacity, commonly because of excessively deep or infinite recursion. Although frequently discussed alongside Java exceptions, StackOverflowError is an Error, not an exception.
class GFG {
static void recursiveMethod() {
recursiveMethod();
}
public static void main(String[] args) {
recursiveMethod();
}
}
Output :
Exception in thread "main" java.lang.StackOverflowErrorExplanation: The recursiveMethod() repeatedly calls itself without a termination condition. Each call consumes stack space until the JVM throws StackOverflowError.
Note: The correct Java name is StackOverflowError, not StackOverflowException. Avoid deliberately catching it as a normal recovery strategy; correct the recursion or use an appropriate iterative approach.
2. User-Defined Exceptions in Java
User-defined exceptions are custom exception classes created by developers to represent application-specific error conditions.
For example, a banking application may need an exception named InsufficientBalanceException when a withdrawal amount exceeds the available account balance.
Custom exceptions can extend:
- Exception to create a checked exception.
- RuntimeException to create an unchecked exception.
Syntax:
class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
An object of this exception class can be thrown using:
throw new MyException("Custom error message");
Example: User-Defined Exception in a Banking Application
The following program creates an InsufficientBalanceException to prevent a withdrawal when the available balance is insufficient.
class InsufficientBalanceException extends Exception {
public InsufficientBalanceException(String message)
{
super(message);
}
}
class BankAccount {
private double balance = 1000.0;
public void withdraw(double amount)
throws InsufficientBalanceException
{
if (amount <= 0) {
throw new IllegalArgumentException(
"Withdrawal amount must be positive");
}
if (amount > balance) {
throw new InsufficientBalanceException(
"Insufficient account balance");
}
balance -= amount;
System.out.println("Withdrawal successful");
}
}
class GFG {
public static void main(String[] args)
{
BankAccount account = new BankAccount();
try {
account.withdraw(1500.0);
}
catch (InsufficientBalanceException e) {
System.out.println(e.getMessage());
}
}
}
Output
Insufficient account balance
Explanation:
- The InsufficientBalanceException class extends Exception, making it a checked exception.
- The withdraw() method validates the withdrawal amount.
- Because 1500 exceeds the available balance of 1000, the method throws InsufficientBalanceException.
- The catch block handles the exception and displays the error message.
The example also uses IllegalArgumentException to reject a non-positive withdrawal amount. This demonstrates how built-in and custom exceptions can be used together.
For financial applications, use BigDecimal or an appropriate monetary type instead of double to avoid floating-point precision problems.
Built-in Vs User-Defined Exceptions
Built-in Exceptions | User-Defined Exceptions |
|---|---|
Provided by Java's standard library. | Created by developers. |
Represent common programming and runtime failures. | Represent application-specific failure conditions. |
Do not require developers to define new exception classes. | Require a custom class extending Exception or RuntimeException. |
Examples: IOException, NullPointerException, ArithmeticException. | Examples: InsufficientBalanceException, InvalidOrderException. |
Can be checked or unchecked. | Can also be checked or unchecked. |
Best Practices for Using Exceptions
- Catch Specific Exceptions: Handle the exception types relevant to an operation instead of broadly catching Exception without a clear reason.
- Use Meaningful Messages: Provide error messages that help identify the failure.
- Preserve Exception Causes: When wrapping exceptions, include the original exception as the cause.
- Avoid Empty Catch Blocks: Do not silently ignore failures.
- Use Try-With-Resources: Close files, streams, and database connections automatically.
- Avoid Exceptions for Normal Control Flow: Validate input and use appropriate return values for expected outcomes.
- Create Custom Exceptions When Needed: Introduce user-defined exceptions when they make application-specific failures clearer.