2

This is more of best practice question.

I'm working with old Java code at the moment. I'm seeing a lot of subclasses of Exception only overwrite the constructors. I'm not sure if there is any practical use of subclassing Exception like this. I think just calling the Exception constructor and pass in a message would be just as effective, and there wouldn't be many subclasses around. Code is liability.

casperOne
  • 73,706
  • 19
  • 184
  • 253
Quincy
  • 1,923
  • 5
  • 27
  • 37

5 Answers5

11

The point of subclassing is that your code can distinguish different types of failure and treat them differently. If you just change the message, then a human can distinguish them in the logs, but that's all.

If the exceptions you are seeing are not actually handled differently, but just caught in a catch-all catch(Exception e) then perhaps someone was being over-enthusiastic with the subclasses, but it is often useful for cleanly separating layers of code and working out which classes should handle which kinds of problem.

For example, one type of exception may indicate a timeout, and it may be appropriate to retry after a short delay, whereas another type of exception indicates an unrecoverable failure (an invalid query, perhaps) which must be thrown up to a higher level or perhaps indicated to the user.

DNA
  • 42,007
  • 12
  • 107
  • 146
2

To add to the other answers:

If you extend Exception and throw it, you're declaring a new checked exception. It will have to be declared on the throws clause of your method. You are saying to the caller: "Here is a unusual case which you must code for".

I think checked exceptions are over-used. They are only really useful in situations where the caller can expect to recover from the problem. The vast majority of exceptions I have seen are the kind that the caller cannot reasonably expect to recover from. In this case you should use a RuntimeException descendant such as IllegalStateException or IllegalArgumentException and let top-level error handling take care of it.

Tim Gage
  • 1,381
  • 10
  • 19
2

This is done to allow more cleaner and more precise catching of exceptions. If all of your code just throws Exception, your exception-handling code will have to look like this:

try {
   // ...
   throw new Exception("configuration error");
   // ...
   throw new Exception("missing value error");
   // etc.
} catch (Exception e) {
   // do something
}

And it will be awkward at the least to handle different kinds of errors in different ways. More importantly, this code will swallow all exceptions, even ones you weren't expecting and for which you haven't written specific error-handling logic. On the other hand, if you write

try {
   // ...
   throw new ConfigurationException();
   // ...
   throw new MissingValueException();
   // etc.
} catch (ConfigurationException e) {
   System.err.println("error: bad configuration");
   System.exit(1);
} catch (MissingValueException e) {
   return DEFAULT_VALUE;
}

you'll be able to easily and cleanly handle different kinds of errors, and won't have to worry that your error handling code will be run in situations that you didn't expect it to.

gsteff
  • 4,764
  • 1
  • 20
  • 17
1
  1. When you have a subclass, you can catch it. You can't catch an exception selectively depending on its message.

  2. Subclasses are more descriptive and easier to use:

    throw new Exception("User does not exist " + userName);
    

    compared to:

    throw new UserNotExistsException(userName);
    

    also the latter exception can have getUserName() method and field accordingly to extract important information when caught. You don't want to parse exception message, don't you?

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
0

Subclassing is the way to go. later in the lifetime of the application you may have to change the exception message. Who knows it may be displayed on a page and the wording needs to be adjusted.

Wrapping the error message in its own Exception subclass helps maintain a clean code and easily test against a given error category.

Olivier Refalo
  • 50,287
  • 22
  • 91
  • 122