简体   繁体   中英

Java, Class-specific Exceptions vs. Standard Exceptions

I've been updating an existing library to throw exceptions to help improve debugging by people using the library.

At first, I thought I'd define exceptions specific to each class, however it turns out most of those exceptions are simply extensions of existing runtime exceptions (eg, FooNegativeIntArgumentException extends IllegalArgumentException , FooNullBarException extends NullPointerException ) with specific messages.

What are the trade-offs of defining new exceptions vs. using existing ones? Are there any conventions/best-practices?

Also, given the need for backwards compatibility, most (if not all) of these exceptions are runtime exceptions.

Here's my take on why we have different types of exception and when to create custom exception types (note: this uses .NET types as examples but the same principles apply to Java and any other language that uses structured error handling). It's probably too long to post here as a complete answer so I'll just post the two key extracts.

  1. When to throw different types of exception? Throw a different type of exception for each symptom that can be programmatically handled differently.

  2. When to create custom exception types? Create a custom exception type when you need to annotate the exception with additional information to aid in the programmatic handling of the symptom.

In your case it doesn't sound like your custom exception types are filling a gap in the symptoms that can be conveyed using standard exceptions, and they aren't adding any additional information for programmatic handling, so don't create them. Just use standard ones instead.

Extending the Exceptions without adding any value like this is a complete waste of time and incurs an ongoing maintenance cost that is best avoided.

Use the standard exceptions.

This is not to say that you should never use custom exceptions, just not in the use cases you present.

Also, when creating custom exceptions, they should be related to the conditions which cause them, not the class from which they might be thrown. It is OK to relate them to a business/functional area, as error conditions which cause exceptions are likely related in this way, and it will provide useful filtering techniques.

From Effective Java

You should favor the use of standard exceptions and use the Java platform libraries set of unchecked exceptions that cover what you described. Reusing exceptions has the following benefits :

Makes your API easier to learn and use because it matches established conventions with which programmers are already familiar

Fewer Exception classes means a smaller memory footprint and less time spent loading classes.

Is it likely that a caller would need to catch FooNegativeIntArgumentException rather than IllegalArgumentException?

My guess is that it will almost never happen, so I would stick with the basic exceptions until you have cases where such differentiation can be seen to be needed.

Trade-off? A lot of work, a lot of code to maintain and time is money . I'd suggest: define new exceptions only if you need them for filtering logs, fine grained exception handling or debugging (set a breakpoint for a special exception type).

I'd use explicitly defined exceptions to give the client code more control. If the client wants to, they can catch IllegalArgumentException as in your example above. If they need more control, they can catch individual types of exceptions. Consider, for example, a method that could throw two subclasses of IllegalArgumentException. If you don't subclass, you have to do string parsing or some other nonsense to determine the actual cause of the thrown exception. User-defined types solves this issue.

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