我为我的应用程序不期望的每个条件创建了异常。UserNameNotValidException, PasswordNotCorrectException等。
然而,我被告知我不应该为这些条件创造例外。在我的UML中,那些是主要流程的异常,那么为什么它不应该是异常呢?
是否有创建异常的指导或最佳实践?
我为我的应用程序不期望的每个条件创建了异常。UserNameNotValidException, PasswordNotCorrectException等。
然而,我被告知我不应该为这些条件创造例外。在我的UML中,那些是主要流程的异常,那么为什么它不应该是异常呢?
是否有创建异常的指导或最佳实践?
当前回答
避免抛出异常的主要原因是抛出异常涉及大量开销。
下面这篇文章指出的一件事是,例外是针对异常条件和错误的。
错误的用户名不一定是程序错误,而是用户错误……
下面是关于。net中的异常的一个不错的起点: http://msdn.microsoft.com/en-us/library/ms229030 (VS.80) . aspx
其他回答
If it's code running inside a loop that will likely cause an exception over and over again, then throwing exceptions is not a good thing, because they are pretty slow for large N. But there is nothing wrong with throwing custom exceptions if the performance is not an issue. Just make sure that you have a base exception that they all inherite, called BaseException or something like that. BaseException inherits System.Exception, but all of your exceptions inherit BaseException. You can even have a tree of Exception types to group similar types, but this may or may not be overkill.
因此,简短的回答是,如果它不会导致显著的性能损失(除非抛出大量异常,否则不应该如此),那么就继续执行。
我的小指南很大程度上受到了“代码完成”这本伟大的书的影响:
使用异常来通知不应该被忽略的事情。 如果错误可以在本地处理,就不要使用异常 确保异常与例程的其余部分处于相同的抽象级别。 异常应该留给真正的异常。
for me Exception should be thrown when a required technical or business rule fails. for instance if a car entity is associated with array of 4 tires ... if one tire or more are null ... an exception should be Fired "NotEnoughTiresException" , cuz it can be caught at different level of the system and have a significant meaning through logging. besides if we just try to flow control the null and prevent the instanciation of the car . we might never never find the source of the problem , cuz the tire isn't supposed to be null in the first place .
在决定异常是否合适时,需要考虑一些有用的事情:
what level of code you want to have run after the exception candidate occurs - that is, how many layers of the call stack should unwind. You generally want to handle an exception as close as possible to where it occurs. For username/password validation, you would normally handle failures in the same block of code, rather than letting an exception bubble up. So an exception is probably not appropriate. (OTOH, after three failed login attempts, control flow may shift elsewhere, and an exception may be appropriate here.) Is this event something you would want to see in an error log? Not every exception is written to an error log, but it's useful to ask whether this entry in an error log would be useful - i.e., you would try to do something about it, or would be the garbage you ignore.
我想说,对于什么时候使用异常并没有硬性规定。然而,使用或不使用它们有很好的理由:
使用异常的原因:
The code flow for the common case is clearer Can return complex error information as an object (although this can also be achieved using error "out" parameter passed by reference) Languages generally provide some facility for managing tidy cleanup in the event of the exception (try/finally in Java, using in C#, RAII in C++) In the event no exception is thrown, execution can sometimes be faster than checking return codes In Java, checked exceptions must be declared or caught (although this can be a reason against)
不使用异常的原因:
Sometimes it's overkill if the error handling is simple If exceptions are not documented or declared, they may be uncaught by calling code, which may be worse than if the the calling code just ignored a return code (application exit vs silent failure - which is worse may depend on the scenario) In C++, code that uses exceptions must be exception safe (even if you don't throw or catch them, but call a throwing function indirectly) In C++, it is hard to tell when a function might throw, therefore you must be paranoid about exception safety if you use them Throwing and catching exceptions is generally significantly more expensive compared to checking a return flag
一般来说,我更倾向于在Java中使用异常,而不是在c++或c#中,因为我认为异常,无论是否声明,都是函数正式接口的基本组成部分,因为更改异常保证可能会破坏调用代码。在Java IMO中使用它们的最大优势是,您知道调用者必须处理异常,这提高了正确行为的机会。
正因为如此,在任何语言中,我总是从一个公共类派生一层代码或API中的所有异常,这样调用的代码就总能保证捕获所有异常。另外,我认为在编写API或库时抛出特定于实现的异常类是不好的(即从较低的层包装异常,以便调用者接收到的异常在您的接口上下文中是可以理解的)。
注意,Java区分了一般异常和运行时异常,因为后者不需要声明。我只会使用运行时异常类,当您知道错误是由程序中的错误导致的。