There are quite a few posts on SO about the "checked vs unchecked exception" topic. This answer is probably the most well-rounded and informative. Yet I'm still conflicted to follow the logic presented there, and there's a reason for that.
I'm building a wrapper API around a set of services similar to each other. There are, however, minor differences between them (or a possibility of such in the future), so that certain functions (of secondary and shortcut nature) may be supported by some services and not supported by others. So it seems only logical to go with the following approach:
public interface GenericWrapperInterface {
void possiblyUnsupportedOperation () throws java.lang.UnsupportedOperationException;
}
Why UnsupportedOperationException
? Because it is designed exactly for this kind of situations.
However, all the relevant SO posts, in addition to Oracle's own manual, postulate that if an exception is used to signal an issue that the client could recover from, or an issue predictable but unavoidable, then that exception should be a checked one. My case conforms to these requirements, because for some operations the possibility of their unavailability may be known in advance and those operations are not critical and may be avoided if needed.
So I'm lost in this conundrum. Should I go with a perfectly fitting standard exception and violate the common logic of exception usage, or should I build my own checked alternative and thus duplicate code and create additional confusion among the API users?
The rule of thumb is that unchecked exceptions represent programmer errors and checked exceptions represent situations. So as the API author you have to decide whether the exceptional condition should have been prevented by the programmer beforehand, or whether the programmer should be required to deal with the condition after it occurs.
The "UnsupportedOperationException" denotes a failure of Java OO model, in particular, a violation of Liskov's Principle.
Usually, that means your code has other, non-OO means to decide if the method in question should be called:
Therefore, calling an unimplemented method is a logic error, on par with assertion failure, stack overflow or running out of memory. As such, it should not be a checked exception.