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

Java Custom Exceptions

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
class InsufficientFundsException extends RuntimeException {
	InsufficientFundsException(String message) {
		super(message);
	}
}
public class Main {
	public static void main(String[] args) {
		try {
			throw new InsufficientFundsException("Not enough balance");
		} catch (InsufficientFundsException e) {
			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
class InvalidAgeException extends RuntimeException {
	int invalidValue;
	InvalidAgeException(String message, int invalidValue) {
		super(message);
		this.invalidValue = invalidValue;
	}
}
public class Main {
	public static void main(String[] args) {
		try {
			throw new InvalidAgeException("Invalid age", -5);
		} catch (InvalidAgeException e) {
			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
class InvalidAgeException extends RuntimeException {
	InvalidAgeException(String message) {
		super(message);
	}
}
public class Main {
	static void checkAge(int age) {
		if (age < 0) {
			throw new InvalidAgeException("Age cannot be negative");
		}
	}
	public static void main(String[] args) {
		try {
			checkAge(-1);
		} catch (InvalidAgeException e) {
			System.out.println("Caught: " + e.getMessage());
		}
	}
}

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.