5
votes

I am creating a object using reflection. Depending on the actual object being constructed, the constructor might have a throws declaration for a particular custom exception and its important I can catch this.

Unfortunately, when I attempt to add the exception to catches of the try block that encompasses the reflective construction, the code will not compile because:

"Unreachable catch block. This exception is never thrown from the try statement body"

I realise that catching the base class Exception would work, and infact that is ok for my code. However, it might not always be the case, since other different exceptions may apply for other objects in the future and using instanceof inside of a catch and re-throwing everything else seems inelegant.

Is there a way to signal that this exception might be thrown, so that I can catch it specifically?

edit: Some code as requested. Does not compile because of above.

try{
  Constructor<? extends Thing> constructor = getClassType().getDeclaredConstructor(SomeParameter.class);
  Thing thing = constructor.newInstance(new SomeParameter());
}
catch(FoobarException e){
  //new Thing(SomeParameter p) might throw this
}
catch(ReflectiveOperationException | IllegalArgumentException | SecurityException e){}
2
I don't think it's possible for reflection to deduce what exceptions a method might throw at compile time - in fact, the reflection API throws it's own exceptions for this reason. I'm not even sure of a way to determine this at run-time :PMadProgrammer
it would be nice to see some codeakf
You can only catch a InvocationTargetExceptionPradeep Pati
@galuano1, I think you should post it as an answerdefault locale

2 Answers

12
votes

The exception will be thrown wrapped in an InvocationTargetException. Catch that and have a look at the cause.

2
votes

Is there a way to signal that this exception might be thrown, so that I can catch it specifically?

No.

Because at the point, any exception thrown by the constructor will have been caught and an InvocationTargetException will have been thrown in its place. This is explained succinctly by the javadoc as follows:

"Throws: [...] InvocationTargetException - if the underlying constructor throws an exception."

(Note that it says "an exception", so this applies to both checked and unchecked exceptions thrown by the constructor.)

So in fact, compiler is telling the truth in that compilation error. The checked exception you were trying to catch cannot possibly be propagating at that point. Indeed, the JLS reachability rules state that the code is definitely unreachable ... hence the compilation error.