简体   繁体   中英

Java best practices when throwing exceptions: throwing core Java exceptions

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: http://rymden.nu/exceptions.html , with humous explanations.

Thanks!

Edit:

Is there a good list of 'core' exceptions?

List so far:

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.

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

IllegalArgumentException

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

IndexOutOfBoundsException

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.

ArithmeticException

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

IllegalStateException

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

DataFormatException

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

TimeoutException

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

KeySelectorException

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.

IOException

Having some problem reading/writing? Throw this exception.

ScriptException

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

GeneralSecurityException

Throw this if you encounter a security-related issue.

RuntimeException

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

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 .netAddress 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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM