- How to create custom exceptions in Java
- 1. Why do I need custom exceptions?
- 2. Writing your own exception class
- 3. Re-throwing an exception which is wrapped in a custom exception
- References:
- Other Java Exception Handling Tutorials:
- About the Author:
- Create a Custom Exception in Java
- 1. Overview
- Further reading:
- Exception Handling in Java
- Checked and Unchecked Exceptions in Java
- Common Java Exceptions
- 2. The Need for Custom Exceptions
- 3. Custom Checked Exception
- 4. Custom Unchecked Exception
- 5. Conclusion
How to create custom exceptions in Java
In the article Getting Started with Exception Handling in Java, you know how to catch throw and catch exceptions which are defined by JDK such as IllegalArgumentException , IOException , NumberFormatException , etc.
What if you want to throw your own exceptions? Imagine you’re writing a student management program and you want to throw StudentException , StudentNotFoundException , StudentStoreException and the like?
So it’s time to create new exceptions of your own.
We will call JDK’s exceptions built-in exceptions and call our own exceptions custom exceptions.
Let me tell you this: Writing custom exceptions in Java is very easy, but the important thing is, you should ask yourself this question:
1. Why do I need custom exceptions?
The answer could be very simple: When you couldn’t find any relevant exceptions in the JDK, it’s time to create new ones of your own.
By looking at the names of the exceptions to see if its meaning is appropriate or not. For example, the IllegalArgumentException is appropriate to throw when checking parameters of a method; the IOException is appropriate to throw when reading/writing files.
From my experience, most of the cases we need custom exceptions for representing business exceptions which are, at a level higher than technical exceptions defined by JDK. For example: InvalidAgeException , LowScoreException , TooManyStudentsException , etc.
2. Writing your own exception class
- Create a new class whose name should end with Exception like ClassNameException . This is a convention to differentiate an exception class from regular ones.
- Make the class extends one of the exceptions which are subtypes of the java.lang.Exception class. Generally, a custom exception class always extends directly from the Exception class.
- Create a constructor with a String parameter which is the detail message of the exception. In this constructor, simply call the super constructor and pass the message.
public class StudentNotFoundException extends Exception < public StudentNotFoundException(String message) < super(message); >>
And the following example shows the way a custom exception is used is nothing different than built-in exception:
public class StudentManager < public Student find(String studentID) throws StudentNotFoundException < if (studentID.equals("123456")) < return new Student(); >else < throw new StudentNotFoundException( "Could not find student with ID " + studentID); >> >
public class StudentTest < public static void main(String[] args) < StudentManager manager = new StudentManager(); try < Student student = manager.find("0000001"); >catch (StudentNotFoundException ex) < System.err.print(ex); >> >
StudentNotFoundException: Could not find student with ID 0000001
3. Re-throwing an exception which is wrapped in a custom exception
It’s a common practice for catching a built-in exception and re-throwing it via a custom exception. To do so, let add a new constructor to our custom exception class. This constructor takes two parameters: the detail message and the cause of the exception. This constructor is implemented in the Exception class as following:
public Exception(String message, Throwable cause)
Besides the detail message, this constructor takes a Throwable ’s subclass which is the origin (cause) of the current exception. For example, create the StudentStoreException class as following:
public class StudentStoreException extends Exception < public StudentStoreException(String message, Throwable cause) < super(message, cause); >>
public void save(Student student) throws StudentStoreException < try < // execute SQL statements.. >catch (SQLException ex) < throw new StudentStoreException("Failed to save student", ex); >>
Here, suppose that the save() method stores the specified student information into a database using JDBC. The code can throw SQLException . We catch this exception and throw a new StudentStoreException which wraps the SQLException as its cause. And it’s obvious that the save() method declares to throw StudentStoreException instead of SQLException .
So what is the benefit of re-throwing exception like this?
Why not leave the original exception to be thrown?
Well, the main benefit of re-throwing exception by this manner is adding a higher abstraction layer for the exception handling, which results in more meaningful and readable API. Do you see StudentStoreException is more meaningful than SQLException , don’t you?
However, remember to include the original exception in order to preserve the cause so we won’t lose the trace when debugging the program when the exception occurred.
And the following code demonstrates handling the StudentStoreException above:
StudentManager manager = new StudentManager(); try < manager.save(new Student()); >catch (StudentStoreException ex)
References:
Other Java Exception Handling Tutorials:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.
Create a Custom Exception in Java
The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.
To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.
Connect your cluster and start monitoring your K8s costs right away:
We rely on other people’s code in our own work. Every day.
It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.
The problem is, of course, when things fall apart in production — debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky.
Lightrun is a new kind of debugger.
It’s one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics.
Learn more in this quick, 5-minute Lightrun tutorial:
Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.
The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.
Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.
Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:
DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema.
The way it does all of that is by using a design model, a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.
And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.
The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.
To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.
Connect your cluster and start monitoring your K8s costs right away:
We’re looking for a new Java technical editor to help review new articles for the site.
1. Overview
In this tutorial, we’ll cover how to create a custom exception in Java.
We’ll show how user-defined exceptions are implemented and used for both checked and unchecked exceptions.
Further reading:
Exception Handling in Java
Checked and Unchecked Exceptions in Java
Common Java Exceptions
2. The Need for Custom Exceptions
Java exceptions cover almost all general exceptions that are bound to happen in programming.
However, we sometimes need to supplement these standard exceptions with our own.
These are the main reasons for introducing custom exceptions:
- Business logic exceptions – exceptions that are specific to the business logic and workflow. These help the application users or the developers understand what the exact problem is.
- To catch and provide specific treatment to a subset of existing Java exceptions
Java exceptions can be checked and unchecked. In the next sections, we’ll cover both of these cases.
3. Custom Checked Exception
Checked exceptions are exceptions that need to be treated explicitly.
Let’s consider a piece of code that returns the first line of the file:
try (Scanner file = new Scanner(new File(fileName))) < if (file.hasNextLine()) return file.nextLine(); >catch(FileNotFoundException e) < // Logging, etc >
The code above is a classic way of handling Java checked exceptions. While the code throws FileNotFoundException, it’s not clear what the exact cause is — whether the file doesn’t exist or the file name is invalid.
To create a custom exception, we have to extend the java.lang.Exception class.
Let’s see an example of this by creating a custom checked exception called IncorrectFileNameException:
public class IncorrectFileNameException extends Exception < public IncorrectFileNameException(String errorMessage) < super(errorMessage); >>
Note that we also have to provide a constructor that takes a String as the error message and called the parent class constructor.
This is all we need to do to define a custom exception.
Next, let’s see how we can use the custom exception in our example:
try (Scanner file = new Scanner(new File(fileName))) < if (file.hasNextLine()) return file.nextLine(); >catch (FileNotFoundException e) < if (!isCorrectFileName(fileName)) < throw new IncorrectFileNameException("Incorrect filename : " + fileName ); >//. >
We’ve created and used a custom exception, so the user can now know what the exact exception is.
Is this enough? We are consequently losing the root cause of the exception.
To fix this, we can also add a java.lang.Throwable parameter to the constructor. This way, we can pass the root exception to the method call:
public IncorrectFileNameException(String errorMessage, Throwable err)
Now the IncorrectFileNameException is used along with the root cause of the exception:
try (Scanner file = new Scanner(new File(fileName))) < if (file.hasNextLine()) < return file.nextLine(); >> catch (FileNotFoundException err) < if (!isCorrectFileName(fileName)) < throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); >// . >
This is how we can use custom exceptions without losing the root cause from which they occurred.
4. Custom Unchecked Exception
In our same example, let’s assume that we need a custom exception if the file name doesn’t contain any extension.
In this case, we’ll need a custom unchecked exception similar to the previous one, as this error will only be detected during runtime.
To create a custom unchecked exception, we need to extend the java.lang.RuntimeException class:
public class IncorrectFileExtensionException extends RuntimeException < public IncorrectFileExtensionException(String errorMessage, Throwable err) < super(errorMessage, err); >>
This way, we can use this custom unchecked exception in our example:
try (Scanner file = new Scanner(new File(fileName))) < if (file.hasNextLine()) < return file.nextLine(); >else < throw new IllegalArgumentException("Non readable file"); >> catch (FileNotFoundException err) < if (!isCorrectFileName(fileName)) < throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); >//. > catch(IllegalArgumentException err) < if(!containsExtension(fileName)) < throw new IncorrectFileExtensionException( "Filename does not contain extension : " + fileName, err); >//. >
5. Conclusion
Custom exceptions are very useful when we need to handle specific exceptions related to the business logic. When used properly, they can serve as a practical tool for better exception handling and logging.
The code for the examples used in this article is available over on GitHub.
Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.
The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.
Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.
Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes: