← Back to Core Java Course | Chapter 10: Exception Handling | Lesson 6 of 8

Java Custom Exceptions

A custom exception is an error type you make yourself with a name that fits your program, like a special warning sign for your own playground. It makes problems clearer.
Syntax
java
class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

Why Custom Exceptions?

Custom exceptions let you represent domain-specific failures with a meaningful name, like InsufficientFundsException, instead of forcing callers to interpret a generic RuntimeException message string.

Example: Why Custom Exceptions?

java
// Define the class InsufficientFundsException
class InsufficientFundsException extends RuntimeException {
	InsufficientFundsException(String message) {
		// Call the parent class constructor
		super(message);
	}
}
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Try code that might throw an exception
		try {
			// Throw InsufficientFundsException to signal an error
			throw new InsufficientFundsException("Not enough balance");
		// Handle InsufficientFundsException if it was thrown
		} catch (InsufficientFundsException e) {
			// Print a line to the console
			System.out.println(e.getMessage());
		}
	}
}

Creating Unchecked Custom Exceptions

Extending RuntimeException creates an unchecked custom exception, meaning callers aren't compiler-forced to catch or declare it — appropriate for programming errors that shouldn't normally be recovered from mid-flow.

Example: Creating Unchecked Custom Exceptions

java
class InvalidAgeException extends RuntimeException { // unchecked: no forced catch
	InvalidAgeException(String message) {
		super(message);
	}
}
public class Main {
	public static void main(String[] args) {
		throw new InvalidAgeException("Age must be positive");
	}
}

Creating Checked Custom Exceptions

Extending Exception directly creates a checked custom exception, forcing every caller to explicitly handle or re-declare it — appropriate for expected, recoverable failure conditions like a file genuinely not existing.

Example: Creating Checked Custom Exceptions

java
class InvalidFileException extends Exception { // checked: must be handled or declared
	InvalidFileException(String message) {
		super(message);
	}
}
public class Main {
	static void open() throws InvalidFileException {
		throw new InvalidFileException("File not found");
	}
	public static void main(String[] args) {
		try {
			open();
		} catch (InvalidFileException e) {
			System.out.println(e.getMessage());
		}
	}
}

Adding Custom Fields and Methods

You can add extra fields to a custom exception, like an error code or the invalid value that caused the failure, giving catch blocks far more to work with than a bare message string.

Example: Adding Custom Fields and Methods

java
// Define the class InvalidAgeException
class InvalidAgeException extends RuntimeException {
	int invalidValue;
	InvalidAgeException(String message, int invalidValue) {
		// Call the parent class constructor
		super(message);
		this.invalidValue = invalidValue;
	}
}
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Try code that might throw an exception
		try {
			// Throw InvalidAgeException to signal an error
			throw new InvalidAgeException("Invalid age", -5);
		// Handle InvalidAgeException if it was thrown
		} catch (InvalidAgeException e) {
			// Print a line to the console
			System.out.println(e.getMessage() + ": " + e.invalidValue);
		}
	}
}

Throwing and Catching Custom Exceptions

Once defined, a custom exception is thrown with throw new MyException(...) just like a built-in one, and caught the same way with a catch block naming that specific type.

Example: Throwing and Catching Custom Exceptions

java
// Define the class InvalidAgeException
class InvalidAgeException extends RuntimeException {
	InvalidAgeException(String message) {
		// Call the parent class constructor
		super(message);
	}
}
// Define the class Main
public class Main {
	static void checkAge(int age) {
		// Check whether age < 0
		if (age < 0) {
			// Throw InvalidAgeException to signal an error
			throw new InvalidAgeException("Age cannot be negative");
		}
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Try code that might throw an exception
		try {
			checkAge(-1);
		// Handle InvalidAgeException if it was thrown
		} catch (InvalidAgeException e) {
			System.out.println("Caught: " + e.getMessage());
		}
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Extending Exception when you meant an unchecked exception, so callers must handle it.
  2. Forgetting to pass the message to super(message).
  3. Creating custom exceptions for cases where a standard one such as IllegalArgumentException is enough.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.