Java best practices when throwing exceptions: throwing core Java exceptions

后端 未结 5 1143
南方客
南方客 2021-02-02 09:07

Instead of throwing new Exception(\"Some message\", maybeSomeCause), which means that all callers of my method will need to catch Exception (which can include Runti

相关标签:
5条回答
  • 2021-02-02 09:15

    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.

    0 讨论(0)
  • 2021-02-02 09:15

    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.

    0 讨论(0)
  • 2021-02-02 09:16

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

    0 讨论(0)
  • 2021-02-02 09:18

    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.

    0 讨论(0)
  • 2021-02-02 09:30

    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.

    0 讨论(0)
提交回复
热议问题