Short answer
- Reflection is verbose by design
- Exception translation is idiomatic (catching lower level exception and abstracting it to a higher level)
- Prefer custom exceptions to
java.lang.Exception
; it's probably too high of an abstraction
Point 1: Avoid reflection if at all possible
Here's a quote from Effective Java 2nd Edition, Item 53: Prefer interfaces to reflection:
[The power of reflection], however, comes at a price:
- You lose all the benefits of compile time checking, including exception checking.
- The code required to perform reflective access is clumsy and verbose. It is tedious to write and difficult to read.
- Performance suffers. Reflective method invocation is much slower than normal method invocation.
[...] As a rule, objects should not be accessed reflectively in normal application at runtime. There are a few sophisticated applications that require reflection. Examples include [omitted on purpose]. If you have any doubts to whether your application falls into one of these categories, it probably doesn't.
Point 2: Exception translation can be a good thing, but don't overuse
Here's a quote from Effective Java 2nd Edition, Item 61: Throw exceptions appropriate to the abstraction.
It is disconcerting when a method throws an exception that has no apparent connection to the task that it performs. This often happens when a method propagates an exception thrown by a lower-level abstraction. [...]
To avoid this problem, higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of higher-level abstraction. This idiom is known as exception translation.
[...] While exception translation is superior to mindless propagation of exceptions from lower layers, it should not be overused. Where possible, the best way to deal with exceptions from lower layers is to avoid them, by ensuring that lower-level methods succeed. [...]
If it is impossible to prevent exceptions from lower layers, the next best thing is to have the higher layer silently work around these exceptions, insulating the caller of the higher-level method from lower-level problems. Under these circumstances, it may be appropriate to log the exception using some appropriate logging facility. This allows an administrator to investigate the problem, while insulating client code and end user from it.
Point 3: java.lang.Exception
is way too general
Looking at the documentation, one can see a long list of direct known subclasses, with a wide-ranging topics from Reflection, RMI, XML parsing, I/O, GUI, cryptography, etc.
Declaring that a method throws Exception
is probably a poor API design decision, because it does not immediately tell the user anything useful about what category the exceptions may be, or under what circumstances they may be thrown. Contrast this with a hypothetical ReflectionException
; this is a lot more informative, and it also allows user to catch specifically ReflectionException
and not, say, an IOException
that somehow slipped through.
Related questions