Programming Pandit

c/c++/c#/Javav/Python


Latest Update

Tuesday, March 11, 2025

Creating Custom Exceptions in Java (User-Defined Exceptions)

 Java allows developers to create their own exceptions to represent application-specific error conditions. Custom exceptions make the code more readable, structured, and meaningful, especially when handling specific scenarios that are not covered by standard exceptions.


📌 Steps to Create a Custom Exception

  1. Create a class that extends Exception (for Checked Exception) or RuntimeException (for Unchecked Exception).
  2. Provide constructors:
    • A default constructor.
    • A constructor with a detailed message.
    • Optionally, a constructor that accepts a Throwable cause.
  3. Override toString() or getMessage() method (Optional but helpful).

📌 Example 1: Checked Exception (Extending Exception)

// Custom Exception Definition

class InvalidAgeException extends Exception {

    public InvalidAgeException(String message) {

        super(message);

    }

}

 

// Using Custom Exception

public class CustomExceptionDemo {

 

    public static void checkAge(int age) throws InvalidAgeException {

        if (age < 18) {

            throw new InvalidAgeException("Age must be at least 18 to register.");

        } else {

            System.out.println("Registration successful. Age: " + age);

        }

    }

 

    public static void main(String[] args) {

        try {

            checkAge(15);  // This will trigger the exception

        } catch (InvalidAgeException e) {

            System.out.println("Exception caught: " + e.getMessage());

        }

    }

}


📌 Output:

Exception caught: Age must be at least 18 to register.


📌 Explanation:

  • The custom exception InvalidAgeException extends the Exception class.
  • The constructor accepts a message and passes it to the superclass (Exception) constructor.
  • The checkAge() method throws the exception if the condition is not met.
  • The exception is caught using a try-catch block.

📌 Example 2: Unchecked Exception (Extending RuntimeException)

// Custom Runtime Exception Definition

class NegativeValueException extends RuntimeException {

    public NegativeValueException(String message) {

        super(message);

    }

}

 

// Using Custom Runtime Exception

public class CustomRuntimeExceptionDemo {

 

    public static int calculateSquareRoot(int num) {

        if (num < 0) {

            throw new NegativeValueException("Negative value: " + num + " is not allowed.");

        }

        return (int) Math.sqrt(num);

    }

 

    public static void main(String[] args) {

        try {

            int result = calculateSquareRoot(-25);  // This will trigger the exception

            System.out.println("Square root: " + result);

        } catch (NegativeValueException e) {

            System.out.println("Exception caught: " + e.getMessage());

        }

    }

}


📌 Output:

Exception caught: Negative value: -25 is not allowed.


📌 Explanation:

  • The custom exception NegativeValueException extends RuntimeException, making it an unchecked exception.
  • Since it's unchecked, we do not need to declare it in a throws clause.
  • We explicitly throw the exception when a negative value is detected.

📌 Best Practices for Creating Custom Exceptions

  1. Use Meaningful Names: The exception name should clearly indicate the problem it represents.
  2. Provide Multiple Constructors: Allow users to pass messages and causes when creating exceptions.
  3. Document Exceptions: Clearly mention in documentation why and when the custom exception might be thrown.
  4. Inherit from RuntimeException only when necessary: Use checked exceptions by default unless you have a strong reason to make them unchecked.
  5. Override toString() or getMessage(): For better debugging messages.

📌 Example 3: Creating Custom Exception with Cause (Advanced)

class DataNotFoundException extends Exception {

    public DataNotFoundException(String message) {

        super(message);

    }

   

    public DataNotFoundException(String message, Throwable cause) {

        super(message, cause);

    }

}

 

public class DataProcessing {

 

    public static void processData(String data) throws DataNotFoundException {

        try {

            if (data == null) {

                throw new NullPointerException("Input data is null.");

            }

            System.out.println("Processing data: " + data);

        } catch (NullPointerException e) {

            throw new DataNotFoundException("Data processing failed due to null data.", e);

        }

    }

 

    public static void main(String[] args) {

        try {

            processData(null);  // This will trigger the custom exception

        } catch (DataNotFoundException e) {

            System.out.println("Exception caught: " + e.getMessage());

            e.printStackTrace();  // Prints the complete exception stack trace

        }

    }

}


📌 Output:

Exception caught: Data processing failed due to null data.

java.DataNotFoundException: Data processing failed due to null data.

    at DataProcessing.processData(DataProcessing.java:12)

    at DataProcessing.main(DataProcessing.java:18)

Caused by: java.lang.NullPointerException: Input data is null.

    at DataProcessing.processData(DataProcessing.java:8)

    ... 1 more


📌 Explanation:

  • The custom exception DataNotFoundException includes a constructor with a cause.
  • When throwing the exception, the cause (NullPointerException) is passed along for better debugging.
  • The stack trace shows the original cause, enhancing error diagnosis.

No comments:

Post a Comment