Creating Custom Exceptions in Java
In Java, sometimes the built-in exception classes are not enough to handle specific error conditions in your program. In such cases, you can create your own custom exceptions.
Custom exceptions help make your code more readable, maintainable, and meaningful by clearly indicating what went wrong.
Why Create Custom Exceptions?
- To handle specific error scenarios unique to your application.
- To improve code readability by providing descriptive exception names.
- To differentiate between different types of errors in complex programs.
Example scenarios:
- Invalid age in a registration form.
- Negative balance in a banking system.
- Invalid input in a calculator program.
How to Create a Custom Exception
Custom exceptions are classes that extend either Exception (checked) or RuntimeException (unchecked).
Syntax – Checked Exception
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
Syntax – Unchecked Exception
public class CustomRuntimeException extends RuntimeException {
public CustomRuntimeException(String message) {
super(message);
}
}
Using a Custom Exception (Checked)
Checked exceptions must be handled using try-catch or declared using throws.
Example:
// Custom Exception
class AgeInvalidException extends Exception {
public AgeInvalidException(String message) {
super(message);
}
}
// Main class
public class CustomExceptionExample {
public static void validateAge(int age) throws AgeInvalidException {
if (age < 18) {
throw new AgeInvalidException("Age must be 18 or above");
} else {
System.out.println("Age is valid: " + age);
}
}
public static void main(String[] args) {
try {
validateAge(15);
} catch (AgeInvalidException e) {
System.out.println("Exception caught: " + e.getMessage());
}
}
}
Output:
Exception caught: Age must be 18 or above
Using a Custom Exception (Unchecked)
Unchecked exceptions do not need to be declared or caught explicitly.
Example:
// Custom Unchecked Exception
class NegativeBalanceException extends RuntimeException {
public NegativeBalanceException(String message) {
super(message);
}
}
// Main class
public class BankAccount {
public static void withdraw(int balance, int amount) {
if (amount > balance) {
throw new NegativeBalanceException("Insufficient balance!");
} else {
System.out.println("Withdrawal successful. Remaining balance: " + (balance - amount));
}
}
public static void main(String[] args) {
withdraw(1000, 1500);
}
}
Output:
Exception in thread "main" java.lang.NegativeBalanceException: Insufficient balance!
Best Practices for Custom Exceptions
- Meaningful Names: Name your exception clearly, e.g.,
InvalidInputException,FileMissingException. - Extend Correct Class: Use
Exceptionfor checked andRuntimeExceptionfor unchecked. - Include Constructors: Provide constructors with
String messageand optionallyThrowable cause. - Avoid Overusing: Use custom exceptions only when necessary.
Example with Cause:
class DatabaseException extends Exception {
public DatabaseException(String message, Throwable cause) {
super(message, cause);
}
}
Key Points to Remember
- Custom exceptions improve code clarity and error handling.
- Checked exceptions require try-catch or throws.
- Unchecked exceptions do not need explicit handling.
- Always provide descriptive messages in exceptions.
- Can be used with inheritance to create a hierarchy of exceptions.
