为什么不鼓励抛出泛型(java.lang.Exception)异常,当它通常足以处理方法中的大多数条件失败时?我理解如果一个方法可以抛出多种类型的异常,那么抛出异常的特定子类可能会稍微澄清一下处理,但在一般的失败/成功情况下,我认为Exception的功能绰绰有余。
答案 0 :(得分:20)
问题是Exception
也是RuntimeException
的超类,它包含一些不应被捕获的东西,因为它表明编程存在问题,而不是由上下文引起的异常情况。在正常情况下,您不希望捕获BufferOverflowException或UnsupportedOperationException。此外,抛出单独的Exception类型可以让调用代码控制如何处理每个类型。使用新的多捕获功能在Java 7中减少了Boilerplate。
答案 1 :(得分:5)
如果抛出更多特定异常,则不会阻止任何调用代码在一个Exception
catch块中处理所有异常。更具体的是更多地记录发生了什么类型的错误,使程序员更容易分别处理它们。
此外,通过抛出“异常”本身,您基本上告诉调用者您的代码,他们不能排除任何类别的异常。可能会出现IOException
,NumberFormatException
等等。
答案 2 :(得分:3)
一如既往:这取决于。
我认为您与其他人公开的API之间存在差异。这可能会存在一段时间。在这种情况下,你不知道调用者最适合他的案例。
另一方面,始终只有您自己内部使用的代码。抛出一般异常可能就足够了。但请记住,您可能希望稍后更改某些异常处理。当所有错误情况一起被破坏时,这将更难。
答案 3 :(得分:1)
通常,您希望了解应用程序中发生的情况,并且只捕获特定的异常,并在您获得未专门定位的异常时让程序失败(或执行顺序更高)。 捕获异常将捕获所有这些,在某些情况下,您不会知道您的程序失败。
答案 4 :(得分:0)
Dittos对GH。我会使用“空指针异常”和“内存不足异常”作为您可能不会在真实应用程序异常的同一块中捕获的异常类型的更明显示例。
我还要补充一点,为未来的可扩展性做一点努力是值得的。如果你在所有地方抛出通用异常,并且稍后你决定需要捕获一些异常而不是其他异常,那么返回并更改它们可能是一个很大的痛苦。但是如果你只是创建你需要的例外,那就不是那么重要了。创建一个新的异常类,只接受带有消息的构造函数,需要什么,5行代码?这是对未来的良好投资。
与编程中的许多事情一样,这是一个你走多远的问题。我通常在我工作的几乎每个项目中创建一个相当通用的“BadInputException”,并在用户输入失败验证标准时抛出它。然后我可以捕获BadInputException并在屏幕上抛出消息。如果我创建一个复杂的类,它会抛出异常数据的异常等等,我通常会为它创建一个异常类。就像我创建一个“TalkToDatabase”类一样,我将创建一个“TalkToDatabaseException”。 (如果有多种例外情况,我知道我想抓住,但至少是一种例外情况,可能更多。)
顺便说一下,我不知道你是否在考虑这个问题,但我强烈反对检查错误信息的文本,以确定错误的类型。我已经看过程序,它们会在所有地方抛出泛型异常,然后在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 ...
}
为这些案例单独制作例外会好得多。处理不仅会更有效率,而且假设您执行上述操作并且稍后有人出现并决定将消息更改为“Foo无效”?该程序仍将编译,但无法正常工作。