How would you create a custom exception in Java?
Creating a custom exception in Java allows you to define your own exception classes that are tailored to your application’s specific needs. Custom exceptions can be used to handle unique error conditions or situations that don’t fit into the standard Java exceptions.
Here’s a step-by-step guide on how to create and use a custom exception:
Steps to Create a Custom Exception in Java:
- Extend the Exception Class:
To create a custom exception, you need to extend either the Exception class (for checked exceptions) or RuntimeException (for unchecked exceptions).
If you want your custom exception to be a checked exception, extend Exception.
If you want it to be an unchecked exception, extend RuntimeException.
- Add Constructors:
Typically, you add constructors to provide flexibility in creating instances of your exception.
Common constructors include:
A default constructor
A constructor that accepts a message (String)
A constructor that accepts both a message and a cause (Throwable)
- Optionally, Override Methods (if needed):
You can override methods like toString() or getMessage() if you want to provide custom behavior for your exception.
Example 1: Custom Checked Exception
// Custom Checked Exception class InvalidAgeException extends Exception { // Constructor with no arguments public InvalidAgeException() { super(“Invalid age provided”); }
// Constructor that accepts a message
public InvalidAgeException(String message) {
super(message);
}
// Constructor that accepts both message and cause
public InvalidAgeException(String message, Throwable cause) {
super(message, cause);
} }
public class CustomCheckedExceptionExample { public static void main(String[] args) { try { validateAge(15); // Throws custom exception } catch (InvalidAgeException e) { System.out.println(“Caught Exception: “ + e.getMessage()); } }
public static void validateAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age must be 18 or older.");
}
System.out.println("Age is valid.");
} }
Output:
Caught Exception: Age must be 18 or older.
Example 2: Custom Unchecked Exception
// Custom Unchecked Exception class InvalidInputException extends RuntimeException { // Constructor with no arguments public InvalidInputException() { super(“Invalid input provided”); }
// Constructor that accepts a message
public InvalidInputException(String message) {
super(message);
}
// Constructor that accepts both message and cause
public InvalidInputException(String message, Throwable cause) {
super(message, cause);
} }
public class CustomUncheckedExceptionExample { public static void main(String[] args) { try { processInput(“invalid”); // Throws custom unchecked exception } catch (InvalidInputException e) { System.out.println(“Caught Exception: “ + e.getMessage()); } }
public static void processInput(String input) {
if ("invalid".equals(input)) {
throw new InvalidInputException("Input cannot be 'invalid'.");
}
System.out.println("Input is valid.");
} }
Output:
Caught Exception: Input cannot be ‘invalid’.
Key Points to Remember:
- Checked vs. Unchecked:
Custom exceptions that extend Exception are checked exceptions, meaning they must either be caught or declared in the method signature with the throws keyword.
Custom exceptions that extend RuntimeException are unchecked exceptions, meaning they do not require explicit handling.
- Constructor Overloading:
It is common to provide multiple constructors in a custom exception class to offer flexibility in how the exception is thrown (with or without messages and causes).
- Provide Meaningful Messages:
Always include meaningful messages when throwing exceptions to make debugging easier.
- Optional Methods:
You can override toString() and getMessage() methods to provide custom string representations of your exception.
Example 3: Custom Exception with Additional Fields
You can add extra fields to your custom exception to provide more detailed information about the error.
class InsufficientFundsException extends Exception { private double amount;
// Constructor with message and amount
public InsufficientFundsException(String message, double amount) {
super(message);
this.amount = amount;
}
public double getAmount() {
return amount;
} }
public class CustomExceptionWithFields { public static void main(String[] args) { try { withdrawMoney(500, 1000); // Throws custom exception } catch (InsufficientFundsException e) { System.out.println(e.getMessage() + “