Java best practices when throwing exceptions: throwing core Java exceptions

Go To


Instead of throwing new Exception("Some message", maybeSomeCause), which means that all callers of my method will need to catch Exception (which can include RuntimeExceptions), I'd like to throw a more specific type of exception when a problem occurs.

I can create my own exception types which extend Exception or another exception type, but I am curious if it is a good idea to re-use some exceptions that come with core Java language, such as:

  • IllegalArgumentException
  • UnsupportedOperationException
  • IOException
  • Others?

Are there others that I am missing? I found a basic list of the 'core' exceptions here:, with humous explanations.



Is there a good list of 'core' exceptions?

List so far:

2012-04-04 17:48
by Jon Onstott
It's always a good idea to use the core exception types where applicable. Only feel the need to reinvent the wheel where absolutely necessary - Mike McMahon 2012-04-04 17:49
The dev docs lists all "core" exception - Attila 2012-04-04 18:01
Use your own Exception types when it makes sense and you want to be more specific. IOException, for example, can mean either your configuration failed to load (broken connection), or it does not exist - ahanin 2012-04-04 18:08


Yes, it's very good to do that. In fact, it's even written about in Effective Java, 2nd ed. See item 60 on page 248: "Favor the use of standard exceptions"

Reusing preexisting exceptions has several benefits. Chief among these, it makes your API easier to learn and use because it matches established conventions with which programmers are already familiar. A close second is that programs using your API are easier to read because they aren’t cluttered with unfamiliar exceptions. Last (and least), fewer exception classes mean a smaller memory footprint and less time spent loading classes.

2012-04-04 17:52
by Jeffrey Blattman


The lists provided in your question are not very usable as quick-reference material, and most descriptions in the dev docs seem cryptic to me.

I haven't run across any short-ish lists of the most reusable built-in exceptions. I've done my best to create one below, but I'm sure it is far from perfect.

github gist link (or see current content below)

List of Potentially Reusable Built-in Exceptions

organized by estimated utility


Thrown to indicate that a method has been passed an illegal or inappropriate argument.


Thrown to indicate that an index of some sort (such as to an array, to a string, or to a vector) is out of range.


Thrown when the requested mathematical operation is non-sensical or impossible. example: int x = 1/0;


The application is not in an appropriate state for the requested operation. example: trying to save before file is loaded or created.


Throw this when you have recieved improperly formatted data. example: MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")


Throw this if something took too long and you're giving up.


I think it makes sense to throw this if you are trying to looking for an object using a key and it was not found or the key is otherwise invalid, but I don't really understand the dev docs on it.

example: myDataStructure.get("lookup_key"); when lookup_key is not in the data structure.


Having some problem reading/writing? Throw this exception.


Running a script of some form and found a problem with it (not I/O or parsing)? Throw this exception.


Throw this if you encounter a security-related issue.


Use this for some runtime-error that doesn't fit well into any other category.

2015-10-04 00:33
by 7yl4r
The description for IllegalStateException is missing an actual example, currently it's "example: trying to ... - leveluptor 2016-08-05 09:06


Absolutely it makes sense to reuse Exception classes when they reasonably describe the scenario that caused the exception to be thrown.

2012-04-04 17:51
by darrengorman


Most core exceptions are too specialized to be used directly, unless you're duplicating existing functionality in the core libs. For instance, you'll probably never need to create an an instance of UnknownHostException; if host resolution fails, the InetAddress or SocketFactory method you called would have already created and thrown the exception.

The only exceptions I've found to be generally usable are IOException, IllegalArgumentException, IllegalStateException, and UnsupportedOperationException.

IOException - All problems with interfaces, networking, and hard drive access fall under this. If you're writing code to access external data or hardware, you should be using this. For instance, if you're implementing an API to access a certain type of network device, you can make a MyDeviceException subclass to be thrown when the device returns an error status or does something strange. There are also some cases where you want to catch an IOException from one or more low-level library calls and wrap it in another IOException with a higher-level message, such as a connectivity check throwing a "Device not available" exception caused by a "Request timed out" exception.

IllegalArgumentException - Any parameter checks should throw this. For example, a negative integer for a size parameter, or an unexpected null. This is an unchecked exception, but I recommend documenting it anyway to make the method preconditions more clear. You can find lots of examples in the core libs.

IllegalStateException - You can use this when the method parameters are valid, but some internal data or functionality required by the method is unavailable, and there isn't a more appropriate checked exception (like IOException). It's often better to design things so that this isn't necessary.

UnsupportedOperationException - If you make a subclass of something and one of the superclass methods is conceptually invalid for it, override it and throw one of these. Guava uses this for its immutable collection classes, since Java's collection interfaces aren't designed to support immutability. This tends to be a sign of bad design in the superclass. Don't use it if just doing nothing or returning null/empty would be an appropriate and unsurprising result.

2017-06-09 20:28
by Sean Van Gorder


If users of your code might need to do different things on two different exceptions, then those should be distinct exception types. That said, the JDK exceptions cover most of the "programmer error" exceptions -- if an IllegalArgumentException is getting thrown, for example, that indicates a programming mistake, not something that should be handled at runtime.

2012-04-04 17:52
by Louis Wasserman