1. Steps to Create a Custom Exception
- Create a new class that extends either
Exception
(for checked exceptions) orRuntimeException
(for unchecked exceptions). - Provide a constructor to initialize the exception message.
- (Optional) Override methods or add additional functionality.
2. Checked vs. Unchecked Custom Exceptions
Type | Extend | Handling Required? | When to Use |
---|---|---|---|
Checked Exception | Exception | ✅ Must handle (try-catch or throws) | External failures (I/O, DB) |
Unchecked Exception | RuntimeException | ❌ Not required | Programming logic errors |
3. Creating a Checked Exception (Extending Exception
)
✅ Use case: If an invalid age is provided, throw InvalidAgeException
.
// Custom Checked Exception
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
public class CheckedExceptionExample {
// Method that throws our custom checked exception
public static void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("Age must be 18 or older.");
}
}
public static void main(String[] args) {
try {
checkAge(16);
} catch (InvalidAgeException e) {
System.out.println("Caught Exception: " + e.getMessage());
}
}
}
✅ Output:
Caught Exception: Age must be 18 or older.
📌 Why extend Exception
?
- Forces the caller to handle or declare the exception using
try-catch
orthrows
.
4. Creating an Unchecked Exception (Extending RuntimeException
)
✅ Use case: If a number is negative, throw NegativeNumberException
.
// Custom Unchecked Exception
class NegativeNumberException extends RuntimeException {
public NegativeNumberException(String message) {
super(message);
}
}
public class UncheckedExceptionExample {
// Method that throws our custom unchecked exception
public static void validateNumber(int num) {
if (num < 0) {
throw new NegativeNumberException("Number cannot be negative.");
}
}
public static void main(String[] args) {
validateNumber(-5); // No try-catch required, but program will crash if not handled
}
}
🛑 Output (Uncaught Exception):
Exception in thread "main" NegativeNumberException: Number cannot be negative.
📌 Why extend RuntimeException
?
- No need for
throws
or forcedtry-catch
. - Useful for developer mistakes (e.g., invalid method arguments).
5. Custom Exception with Additional Fields
You can add extra fields like an error code for more information.
class CustomExceptionWithCode extends Exception {
private int errorCode;
public CustomExceptionWithCode(String message, int errorCode) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
}
public class ExceptionWithCodeExample {
public static void checkValue(int value) throws CustomExceptionWithCode {
if (value < 0) {
throw new CustomExceptionWithCode("Negative values not allowed!", 1001);
}
}
public static void main(String[] args) {
try {
checkValue(-10);
} catch (CustomExceptionWithCode e) {
System.out.println("Error Code: " + e.getErrorCode() + ", Message: " + e.getMessage());
}
}
}
✅ Output:
Error Code: 1001, Message: Negative values not allowed!
6. Best Practices for Custom Exceptions
✔ Use checked exceptions for recoverable situations (e.g., invalid input, business rules).
✔ Use unchecked exceptions for developer errors (e.g., null values, invalid method calls).
✔ Provide meaningful exception messages for easier debugging.
✔ Avoid overusing custom exceptions—use built-in Java exceptions when possible.