16

I'm defining a new interface API... admittedly not something I do all that often. I'd like to define the interface methods to throw an Exception to allow some flexibility for the implementers. They can then choose to throw an Exception, throw a more specific subclass of Exception, or throw nothing at all. I've read a couple of times that while its good to allow implementing classes this flexibility, it's also bad to define the interface method with "throws Exception". Instead, it's recommended to subclass Exception (e.g. MyException) and throw the subclass. The explanations for this practice were lacking in detail, so can someone elaborate on this best practice please? Thanks.

user1491636
  • 2,355
  • 11
  • 44
  • 71
  • You certainly don't want to throw a generic Exception, that does pretty much no good at all. – Andrew Dec 11 '13 at 21:34
  • 1
    Good for thinking ahead! – Alec Teal Dec 11 '13 at 21:39
  • The answer is pretty simple: _YOU_ are responsible to handle the exception (Since you are allowing exceptions in the first place). So define Exception(s) you can handle. – mrak Dec 11 '13 at 21:39
  • 6
    You don't want to 'allow some flexibility to implementors'. You are defining the interface that they must implement. So define it. – user207421 Dec 11 '13 at 21:48
  • 1
    For a question that was closed for being opinion-based, it is a very helpful question, as indicated by the number of up-votes. We need a way to let these questions live (and be answered with opinion) in SO. – Jonathan M Jul 11 '19 at 15:54

6 Answers6

12

I can appreciate trying to give the implementers some flexibility, but the exception is part of the API, so you should put some thought into what (checked) exception(s) makes sense.

By saying throws Exception, you are not helping the clients of the interface understand what kinds of failures are expected to give them a chance to react to them appropriately. You can consider akin to accepting a method parameter of Object to allow implementers to decide what arguments they can accept. Its good for the implementer, but a nightmare for the clients of the interface.

Bert F
  • 85,407
  • 12
  • 106
  • 123
3

Better have an idea what exceptions you need to throw later. There's the so called Liskov substitution principle, which recommends not to throw exceptions in subclasses that would not be thrown by the super class.

Liskov substitution principle aka. design by contract: http://en.wikipedia.org/wiki/Liskov_substitution_principle

If you are uncertain which Exception need to be thrown, use "throws Exception" (even if it is uncool). Just do not allow unexpected behaviour by implementing classes when they throw exceptions where they weren't planned by you.

The worst case would be a programmer who desperately throws runtime exceptions because of a lack of throws-declarations.

rulebot
  • 232
  • 3
  • 7
2

I prefer to throw Java standard subclass of RuntimeException. This gives the flexibility of allowing the Exception to propagate or be caught without having references to your API.

There are many subclasses to choose from http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html

Often I use IllegalStateException or IllegalArgumentException

JustinKSU
  • 4,875
  • 2
  • 29
  • 51
  • 1
    Throwing a `RuntimeException` (thus no throws in the method signature) prevents the implementation or the client to have any fore-sight into what problems may occur. – Don Cheadle Apr 06 '15 at 14:53
  • 3
    You CAN have runtime exceptions documented in your throws cause. The question is whether you want to force your user to handle it. I think Java community has moved away from using checked exceptions for most things. – JustinKSU Apr 06 '15 at 20:35
2

Think of checked exceptions as optional return values. The API whose methods return Object is understandably rare, and the same principle should apply for checked exceptions.

Judge Mental
  • 5,209
  • 17
  • 22
1

The reason for saying that an interface method declaring to throw the base class Exception is bad practice is because it would in fact make throwing an instance of that very base class a legal implementation of the interface, which is what you clearly want to avoid.

This is why you would only use specialized/custom exception types in your signatures.

I wouldn't go as far as saying that an interface should not declare a throwing of any Exception in advance, as someone said in his answer previously, because the interface is in fact not free floating.

You, as the one declaring the interface, invoke or use the methods in a certain way, and you make assertions on how the methods will be used by your side of the code.

It is in fact a contract that you create. And exceptions are a part of that contract. In fact the one using the interface (not the one implementing it) will be done with his work way before an implementation may exist.

mwhs
  • 5,878
  • 2
  • 28
  • 34
1

in general, throwing an exception means one of the two options:

  1. asking the caller to take an action based on something that happened, usually hoping he has a broader / better understanding of the situation to take a decision
  2. Notify the caller that the action failed beyond repair

focusing on the first type throwing specific exceptions is a good idea and the called can than do:

try {
} catch (ServerIsBusyException ex) {
    // wait 10 sec and continue / try another server
} catch (BadUserNameException ex2) {
   // try another name
} ....

second type is usually RuntimeException s that means an unexpected situation

see a good explanation in this answer

Community
  • 1
  • 1
Guy Gavriely
  • 11,228
  • 6
  • 27
  • 42