java 不鼓励抛出通用异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7959461/
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
Throwing generic Exception discouraged?
提问by oldSkool
Why is it discouraged to throw a generic (java.lang.Exception) exception, when it is usually sufficient to handle most conditional failures within a method? I understand that if a method could throw multiple types of exceptions then throwing specific subclasses of an exception might clarify the handling a bit, but in a general fail/succeed case I think Exception serves more than adequate.
为什么不鼓励抛出泛型 (java.lang.Exception) 异常,因为它通常足以处理方法中的大多数条件失败?我知道如果一个方法可以抛出多种类型的异常,那么抛出异常的特定子类可能会稍微澄清一下处理方式,但在一般的失败/成功情况下,我认为 Exception 服务绰绰有余。
回答by G_H
The problem is that Exception
is also the superclass of RuntimeException
, which encompasses some stuff that shouldn't be caught as it indicates a problem with the programming rather than an exceptional condition that arises from context. You don't want to catch a BufferOverflowException or UnsupportedOperationException under normal circumstances. Besides, throwing separate Exception types gives the calling code control over how to handle each one. Boilerplate is reduced in Java 7 with the new multi-catch feature.
问题是这Exception
也是 的超类RuntimeException
,它包含一些不应该被捕获的东西,因为它表明编程存在问题,而不是上下文引起的异常情况。在正常情况下,您不想捕获 BufferOverflowException 或 UnsupportedOperationException。此外,抛出单独的异常类型使调用代码可以控制如何处理每个异常类型。样板文件在 Java 7 中通过新的多捕获功能减少。
回答by Mark Peters
If you throw more specific exceptions, that does not stop any calling code from dealing with all of them in one Exception
catch block. Being more specific is more documenting as to what type of errors occur, making it easier for programmers to deal with them separately.
如果您抛出更具体的异常,这不会阻止任何调用代码在一个Exception
catch 块中处理所有异常。更具体的是更多地记录发生什么类型的错误,使程序员更容易分别处理它们。
Additionally, by throwing "Exception" itself you're basically telling callers of your code that they can't rule out any class of exception. An IOException
might occur, as might a NumberFormatException
, etc.
此外,通过抛出“异常”本身,您基本上是在告诉代码的调用者,他们不能排除任何类型的异常。anIOException
可能发生,aNumberFormatException
等也可能发生。
回答by DerMike
As always: It depends.
一如既往:这取决于。
I think there is a difference between API that you expose to others. That may live for some time. In that case you don't know what the caller considers best for his case.
我认为您向他人公开的 API 之间存在差异。那可能会活一段时间。在这种情况下,您不知道来电者认为什么最适合他的情况。
On the other hand there always is code that you use internally only for yourself. Than it might be sufficient to throw an generic exception. But remember, that you might want to change some exception handling later on. That will be harder when all error cases are mangled together.
另一方面,总有一些代码仅供您自己在内部使用。比抛出通用异常可能就足够了。但请记住,您可能希望稍后更改某些异常处理。当所有的错误案例都混杂在一起时,这将更加困难。
回答by Roman Goyenko
Generally you want to know what happened in you app and only catch specific exceptions and let the program fail (or go higher in execution order) when you get the exception that you don't specifically target. Catching Exception will catch them all and in some cases you wouldn't know your program is failing.
通常,您想知道您的应用程序中发生了什么,并且只捕获特定的异常,并在遇到您没有专门针对的异常时让程序失败(或执行顺序更高)。捕获异常会捕获所有异常,并且在某些情况下您不会知道您的程序失败了。
回答by Jay
Dittos to GH. I would have used "null pointer exception" and "out of memory exception" as more obvious examples of the kind of exceptions you probably don't watch to catch in the same block with your true application exceptions.
同上GH。我会使用“空指针异常”和“内存不足异常”作为更明显的示例,说明您可能不会在与真正的应用程序异常相同的块中捕获的异常类型。
I'd also add that it pays to go to a little effort for future expandability. If you throw generic Exceptions all over the place, and later you decide that you need to catch some exceptions and not others, it can be a major pain to go back and change them all. But if you just create the exceptions you need as you go along, it's not that big a deal. Creating a new exception class that just accepts a constructor with a message takes, what, 5 lines of code? It's good investment for the future.
我还要补充一点,为未来的可扩展性付出一点努力是值得的。如果您到处抛出通用异常,然后您决定需要捕获一些异常而不是其他异常,那么返回并更改它们可能会很痛苦。但是,如果您只是在进行过程中创建所需的例外,那就没什么大不了的。创建一个只接受带有消息的构造函数的新异常类需要什么,5 行代码?这是对未来的良好投资。
Like many things in programming, it's a question of how far you go. I usually create a rather generic "BadInputException" in almost every project I work on, and throw this any time user inputs fail validation criteria. Then I can just catch BadInputException and throw the message on the screen. If I create a complex class that throws exceptions for inconsistent data and that sort of thing, I usually create an exception class for it. Like if I create a "TalkToDatabase" class, I'll create a "TalkToDatabaseException". (Maybe more than that if there are multiple kinds of exceptions I know I want to catch, but at least the one.)
就像编程中的许多事情一样,这是一个你能走多远的问题。我通常在我从事的几乎每个项目中创建一个相当通用的“BadInputException”,并在用户输入未通过验证标准时抛出它。然后我可以捕获 BadInputException 并将消息抛出到屏幕上。如果我创建一个复杂的类,为不一致的数据和类似的事情抛出异常,我通常会为它创建一个异常类。就像如果我创建一个“TalkToDatabase”类,我将创建一个“TalkToDatabaseException”。(如果有多种异常,我知道我想捕获,但至少是一种。)
And by the way, I don't know if you're thinking of this, but I would strongly discourage examining the text of an error message to determine the type of error. I've seen programs where they throw generic Exceptions all over the place, and then in catch blocks they have code like
顺便说一句,我不知道您是否考虑过这一点,但我强烈建议您不要检查错误消息的文本以确定错误类型。我见过他们到处抛出通用异常的程序,然后在catch块中他们有这样的代码
// Very bad idea! Don't do this!
catch (Exception ex)
{
if (ex.getMessage().equals("Invalid foo"))
... handle bad foo ...
else if (ex.getMessage().equals("Plugh is over maximum"))
... handle bad plugh ...
... etc ...
}
It would be much better to just make separate Exceptions for these cases. Not only will processing be much more efficient, but suppose you do the above and somebody comes along later and decides to change the message to "Foo is invalid"? The program will still compile, but it won't work correctly.
为这些情况单独设置例外会好得多。不仅处理效率会更高,而且假设您执行上述操作并且稍后有人决定将消息更改为“Foo 无效”?该程序仍将编译,但将无法正常工作。