Java界面抛出exception最佳实践

我正在定义一个新的接口API ……诚然,这不是我经常做的事情。 我想定义接口方法来抛出exception,为实现者提供一些灵活性。 然后,他们可以选择抛出exception,抛出一个更具体的Exception子类,或者根本不抛出任何东西。 我已经阅读过几次虽然很好地允许实现类这种灵活性,但使用“throws Exception”定义接口方法也是不好的。 相反,建议inheritanceException(例如MyException)并抛出子类。 对这种做法的解释缺乏细节,那么有人可以详细说明这种最佳做法吗? 谢谢。

我可以尝试给实现者一些灵活性,但exception是API的一部分,所以你应该考虑一下(检查的)exception是有意义的。

通过说throws Exception ,你没有帮助界面的客户理解预期会有什么样的失败让他们有机会对它们作出适当的反应。 您可以考虑接受Object的方法参数,以允许实现者决定他们可以接受哪些参数。 它对实现者有好处,但对于界面的客户来说却是一场噩梦。

更好地了解您需要稍后抛出的exception。 有所谓的Liskov替换原则,它建议不要在超类不会抛出的子类中抛出exception。

利斯科夫替代原则又名。 按合同设计: http : //en.wikipedia.org/wiki/Liskov_substitution_principle

如果您不确定需要抛出哪个Exception,请使用“throws Exception”(即使它是uncool)。 只是在他们没有为您规划的情况下抛出exception时,不要通过实现类来允许意外行为。

最糟糕的情况是程序员由于缺少throws-declarations而拼命抛出运行时exception。

我更喜欢抛出RuntimeException Java标准子类。 这样可以灵活地允许在不引用API的情况下传播或捕获exception。

有许多子类可供选择http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html

我经常使用IllegalStateExceptionIllegalArgumentException

将已检查的exception视为可选返回值。 其方法返回Object的API很少见,并且相同的原则应适用于已检查的exception。

说声明抛出基类Exception的接口方法是不好的做法的原因是因为它实际上会使该基类的实例成为接口的合法实现,这是您显然想要避免的。

这就是您只在签名中使用专门/自定义exception类型的原因。

我不会说接口不应该提前声明抛出任何exception,正如有人在之前的回答中所说,因为接口实际上不是自由浮动的。

作为声明接口的人,您以某种方式调用或使用这些方法,并对代码方使用方法的方式进行断言。

它实际上是您创建的合同。 例外是该合同的一部分。 事实上,在实现可能存在之前,使用接口(而不是实现它的接口)的接口将以他的工作方式完成。

通常,抛出exception意味着两个选项之一:

  1. 要求呼叫者根据发生的事情采取行动,通常希望他对情况有更广泛/更好的理解来做出决定
  2. 通知呼叫者该操作失败无法修复

专注于第一类抛出特定exception是一个好主意而且被调用可以做到:

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

第二种类型通常是RuntimeException,这意味着意外情况

在这个答案中看到一个很好的解释