Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can throwing Exception be a good way to handle all of the exceptions that are thrown in Java's reflection API?

I find that Java's reflection API is exception verbose, and I often want to catch each specific exception, but just throw Exception. Is this poor practice, or do you really throw all of those exceptions on the method signature? Every method that calls that method must then deal with each of those specific exceptions in some way. Instead, I'm thinking of doing this:

public void someMethod()
        throws Exception {

    try {

        // do a bunch of reflection...

    } catch(ClassCastException classCastException) {

        throw new Exception("Some specific message.", classCastException);

    } catch(InvocationTargetException invocationTargetException) {

        throw new Exception("Some specific message.", invocationTargetException);

    }
}

Is that poor practice?


2 Answers

Rethrowing different kinds of exceptions that a method throws as a single unified exception can sometimes be a reasonable approach.

Using java.lang.Exception specifically for this is a bad idea, because it's too unspecific.

You might rethrow each different exception as some custom MyException or something like that. That's sometimes a reasonable approach when you're not really interested in why someMethod failed.

like image 138
Joachim Sauer Avatar answered Oct 23 '25 21:10

Joachim Sauer


Short answer

  • Reflection is verbose by design
  • Exception translation is idiomatic (catching lower level exception and abstracting it to a higher level)
    • ... but don't overuse!
  • 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

  • In Java, is using throws Exception instead of throwing mulitple specific exceptions good practice?
  • Catching several exceptions and rethrowing a general exception
  • java.lang.Exception vs. rolling your own exception
  • When should Throwable be used instead of new Exception?
  • Need authoritative source for why you shouldn’t throw or catch java.lang.Exception
  • In Java, when should I create a checked exception, and when should it be a runtime exception?
  • When to choose checked and unchecked exceptions
  • The case against checked exceptions
like image 40
polygenelubricants Avatar answered Oct 23 '25 21:10

polygenelubricants