When I throw checked exceptions from a method should I just declare the super class of the exceptions in the method signature or all the different types? If I have the follo
The throws
clause is there to convey useful information to the calling method about what might go wrong during invocation of this method. That means that how specific you are will depend on how much information you want to convey; and that will be application-dependent.
For instance, declaring throws Exception
is almost always a bad idea: the information this conveys is just "something might go wrong", which is too vague to be useful. But whether calling classes are going to need perfectly fine-grained information in the throws
clause is something you need to decide by looking at your program. There's no set answer.
If the different sub types need different handling, then definitely declare the two different exceptions. Never expect the developer using your method to guess that you are actually throwing different types of exceptions.
If you declare two distinct exceptions, and the user knows from the Javadoc that they are actually descendents of the same class, the user may choose to catch them both with a catch (SuperException e)
rather than two individual catch clauses. But it depends on the user's choice.
If you don't declare them separately, your IDE is not going to add the appropriate @Throws
to your Javadoc comment. And your Javadoc will therefore only indicate that you're throwing SuperException
, which will leave the user in the dark. Solving this by just putting it in the text of the comment is not a real solution. If any tool is using reflection to determine what your method throws, it will not see the individual exceptions in the array returned from Method.getExceptionTypes()
.
If the functionality expected of the different exceptions is more or less the same and it's just a matter of how they will appear in the logs, it may be better to just use the parent exception, with different messages.
The interface should be as stable as possible. So probably Super. Many libraries use the "Super" strategy, because exception specs cause far more annoyance in maintainability than readability or safety they add. Even the IOException is a Super that nearly all Java library code uses instead of declaring more specific exceptions. (But when they do declare more specific exceptions, it's because the contract is that more general IOExceptions won't be thrown. Read on.)
You might list Sub1 and Sub2 if you really do want to say each of those exceptions can be thrown, but don't want to say that any derivative of Super can be thrown. Perhaps Sub1 is NumberCrunchException and your method calls crunchNumbers() and users of your method can be assured that's the only exception-ful thing your method does. In that case the specific strategy is better.