Java接口抛出异常最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20530221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java interface throws Exception best practice
提问by user1491636
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.
我正在定义一个新的接口 API... 诚然,这不是我经常做的事情。我想定义接口方法来抛出异常,以便为实现者提供一些灵活性。然后他们可以选择抛出一个异常,抛出一个更具体的异常子类,或者什么都不抛出。我读过几次,虽然允许实现类的这种灵活性很好,但用“抛出异常”定义接口方法也很糟糕。相反,建议子类化 Exception(例如 MyException)并抛出子类。对这种做法的解释不够详细,所以有人可以详细说明这种最佳做法吗?谢谢。
回答by mwhs
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.
之所以说声明抛出基类的接口方法Exception
是不好的做法是因为它实际上会使抛出该基类的实例成为接口的合法实现,这显然是您想要避免的。
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.
它实际上是您创建的合同。例外是该合同的一部分。事实上,使用接口的人(不是实现它的人)将在实现之前以他的工作方式完成。
回答by JustinKSU
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.
我更喜欢抛出 .java 的标准子类RuntimeException
。这提供了允许异常传播或被捕获而无需引用您的 API 的灵活性。
There are many subclasses to choose from http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html
有许多子类可供选择http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html
Often I use IllegalStateException
or IllegalArgumentException
我经常使用IllegalStateException
或IllegalArgumentException
回答by Bert F
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.
我很欣赏尝试给实现者一些灵活性,但异常是 API 的一部分,所以你应该考虑一下什么(检查的)异常是有意义的。
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.
这么说throws Exception
,您并没有帮助接口的客户了解预期什么样的故障可以让他们有机会对它们做出适当的反应。您可以考虑类似于接受 的方法参数Object
以允许实现者决定他们可以接受哪些参数。它对实现者有好处,但对接口的客户来说却是一场噩梦。
回答by rulebot
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 替换原则,它建议不要在超类不会抛出的子类中抛出异常。
Liskov substitution principle aka. design by contract: http://en.wikipedia.org/wiki/Liskov_substitution_principle
Liskov 替代原则又名。合同设计: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.
如果您不确定需要抛出哪个 Exception,请使用“throws Exception”(即使它不酷)。只是不要通过实现类来允许意外行为,因为它们在您未计划的情况下抛出异常。
The worst case would be a programmer who desperately throws runtime exceptions because of a lack of throws-declarations.
最糟糕的情况是程序员由于缺少 throws 声明而拼命抛出运行时异常。
回答by Judge Mental
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.
将检查异常视为可选的返回值。Object
可以理解,返回方法的 API很少见,同样的原则也适用于受检异常。
回答by Guy Gavriely
in general, throwing an exception means one of the two options:
一般来说,抛出异常意味着以下两个选项之一:
- 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
- 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
第二种类型通常是 RuntimeException ,表示意外情况
see a good explanation in this answer
在这个答案中看到一个很好的解释