Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • http://rymden.nu/exceptions.html
  • Java 7 Exception class API
like image 787
Jon Onstott Avatar asked Apr 04 '12 17:04

Jon Onstott


People also ask

Is it good practice to throw exception in Java?

The short answer is NO. You would throw an exception if the application can't continue executing with the bad data. In your example, the logic is to display an error message on the front end and Option 2 is the cleaner method for achieving this requirement.


4 Answers

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.

like image 164
Jeffrey Blattman Avatar answered Oct 12 '22 17:10

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

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.

like image 20
7yl4r Avatar answered Oct 12 '22 17:10

7yl4r


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.

like image 3
Sean Van Gorder Avatar answered Oct 12 '22 17:10

Sean Van Gorder


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

like image 1
darrengorman Avatar answered Oct 12 '22 18:10

darrengorman