2

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?

Semisonic
  • 1,152
  • 8
  • 21
  • If it's known before-hand that the operation is not supported, calling it should raise an unchecked exception, because that is a programming error that should not have occurred. – ZhongYu Feb 15 '17 at 16:15
  • @ZhongYu, the client code may be aware of the possibility of the lack of support, but whether each particular implementation object has that support or not may be unknown until run-time. – Semisonic Feb 15 '17 at 18:57

2 Answers2

2

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:

if (instance.isSupportive()) instance.possiblyUnsupportedOperation();

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.

  • I get what you're saying. However, let's say that the interface has a whole multitude of methods which might be either supported or not. Creating a separate tester method for each of them, or mapping the methods onto some Enum to pass the method descriptor into a tester function - isn't it an even uglier solution codewise? After all, even the Java core classes like those from the Collections Framework use `UnsupportedOperationException` to indicate whether a certain operation is available for a particular container. And since Java is already imperfect per se, shouldn't I follow its own rules? – Semisonic Feb 15 '17 at 15:59
  • If you expect the unavailable methods to be routinely called and use the the exception as a sort of out-of-band return value, then your design is even more off than I assumed. In that case, use some other CHECKED exception, not `UnsupportedOperationException`. –  Feb 15 '17 at 21:49
  • Considering `UnsupportedOperationException` in Collections Framework: one example of its use is modifying methods in Unmodifiable collections. In that case, you're not expected to just blindly add an element - an attempt to call add() on an `UnmpodifiableList` would be a logic error. Your case seems to be different. Please review your OO design... –  Feb 15 '17 at 21:51
0

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.

Lew Bloch
  • 3,364
  • 1
  • 16
  • 10