Java allows us to create our own exception class and throw the created exception using throw keyword. These exceptions are known as the Custom Exception or User-Defined Exception. In this article, we will learn how to create Custom Exception in Java, including both Custom Checked Exception and Custom UnChecked Exception.
Why we need Custom Exceptions?
Java has a lot of built exceptions such as IOException, NullPointerException, etc, but these exceptions will not always be the best fit for the business requirements. We will mostly need the custom exception for the business needs rather than technical issues.
For example, IOException can be thrown when a particular file is not present and NullPointerException can be thrown when a particular entity is null but these exceptions cannot be used in a scenario where you are validating a user and we might need to throw an InvalidUserException rather than a predefined exception.
Custom Checked Exception / Custom Compile time Exception
Let’s create a Custom Checked Exception, which will be thrown whenever an invalid user name is keyed in. In order to create a custom compile time exception all you have to do is to extend Exception class.
package com.javainterviewpoint; public class InvalidUserException extends Exception { public InvalidUserException(String message) { super(message); } }
The Custom exception (InvalidUserException) class has a constructor that takes a string error message as a parameter and in turn calls the parent class constructor using the super keyword.
So why do we need to call the base class constructor using super?
Can’t we ignore this call?
It is necessary to initialize the base class as the first step before construction of the derived class object. If no explicit call is made then Java will call the default no parameter constructor of the Exception class and the message/cause will be missed. Therefore, it is good practice to use the super keyword to call the parameterized constructor of the base class and initialize it with the error message.
Now let’s see how to throw our custom compile time exception in our UserValidator class.
package com.javainterviewpoint; import java.util.Scanner; public class UserValidator { public static void main(String[] args) throws InvalidUserException { Scanner scanner = new Scanner(System.in); System.out.println("Enter the username to validate :"); String userName = scanner.nextLine(); if(userName.equals("JIP")) System.out.println("Valid username entered"); else throw new InvalidUserException("Invalid username entered"); } }
In the above code we are validating the username entered, if the username entered is equal to “JIP” then we are simply printing the message “Valid username entered”, else we are throwing InvalidUserException with the message “Invalid username entered”
Note: Since the checked exception follows handle or declare rule, we have declared our custom checked exception using the throws keyword at the method signature.
Output:
Enter the username to validate : Java Exception in thread "main" com.javainterviewpoint.InvalidUserException: Invalid username entered at com.javainterviewpoint.UserValidator.main(UserValidator.java:16)
Custom UnChecked Exception / Custom Runtime Exception
The above way of creating user-defined exception works fine but it will force us to either handle the exception using try catch or declare the user-defined exception using throws keyword.
In order to overcome the above said issues, we can create custom unchecked exception, all you have to do is to extend RuntimeException class.
package com.javainterviewpoint; public class InvalidAgeException extends RuntimeException { public InvalidAgeException(String message) { super(message); } } package com.javainterviewpoint; import java.util.Scanner; public class AgeValidator { public static void main(String[] args) throws InvalidUserException { Scanner scanner = new Scanner(System.in); System.out.println("Enter the Age to validate :"); int age = scanner.nextInt(); if(age > 1 && age < 150) System.out.println("Valid Age entered"); else throw new InvalidAgeException("Invalid Age entered"); } }
In the above code we are just validating the age entered, if the age entered is greater than 1 and less than 150 then we are simply printing the message “Valid Age entered”, else we are throwing InvalidAgeException with the message “Invalid Age entered”
Output:
Enter the Age to validate : 255 Exception in thread "main" com.javainterviewpoint.InvalidAgeException: Invalid Age entered at com.javainterviewpoint.AgeValidator.main(AgeValidator.java:16)
Note: we did not use the throws keyword at the message signature to declare our custom exception since it is an unchecked exception. The client who is calling our AgeValidator class will have to use a try catch to handle the exception when occurred.
Preserving the Exception stack and Re-throwing using Custom Exception
It is a common practice to catch the built-in Java exception and throw the user-defined exception with additional information which can be error status codes or custom error message etc. We need to be sure that we are not losing any stack trace which will help us to debug.
All we need to do is create a custom exception either checked or unchecked exception with a constructor which takes the error message and cause as a parameter.
package com.javainterviewpoint; public class InvalidUserException extends Exception { public InvalidUserException(String message, Throwable cause) { super(message, cause); } public InvalidUserException(String message) { super(message); } } package com.javainterviewpoint; import java.util.Scanner; public class UserValidator { public static void main(String[] args) throws InvalidUserException { try { Scanner scanner = new Scanner(System.in); System.out.println("Enter the username to validate :"); String userName = scanner.nextLine(); if (userName.equals("JIP")) System.out.println("Valid username entered"); else throw new Exception(); } catch (Exception e) { throw new InvalidUserException("Invalid username entered", e); } } }
In the InvalidUserException class, we have added a new constructor with two parameters one for holding the error message and other holding the cause (Throwable) and both the parameters are passed to the base class using super()
Output:
Enter the username to validate :
Java
Exception in thread "main" com.javainterviewpoint.InvalidUserException: Invalid username entered
at com.javainterviewpoint.UserValidator.main(UserValidator.java:22)
Caused by: java.lang.Exception
at com.javainterviewpoint.UserValidator.main(UserValidator.java:19)
Leave a Reply