2011-10-31 136 views
12

当通常足以处理方法中的大多数条件失败时,为什么不鼓励抛出通用(java.lang.Exception)异常?我知道如果一个方法可以抛出多种类型的异常,那么抛出一个异常的特定子类可能会澄清一点处理,但在一般的失败/成功案例中,我认为异常服务已经足够。投掷泛型异常不鼓励?

+0

[Java或C#中异常管理的最佳实践]的可能重复(http://stackoverflow.com/questions/409563/best-practices-for-exception-management-in-java-or-c-sharp) –

回答

20

的问题是,Exception也是RuntimeException超类,其中包括了一些东西,不应该被抓住,因为它表明与编程问题,而不是一个特殊的条件是由上下文产生的。在正常情况下,您不想捕获BufferOverflowException或UnsupportedOperationException。此外,抛出单独的异常类型给调用代码控制如何处理每一个。新的多捕获功能在Java 7中减少了锅板数量。

+1

这是另一个重要问题,+1。 –

+0

@MarkPeters虽然我很少说“从不”,因为我认为即使是最糟糕的反模式在扭曲的情况下也是正确的答案,所以最好小心一些例外情况。有时候他们必须通过你没有写的代码来处理,最终会在整个商店泄漏抽象。那么,当然,还有那些追上'Throwable'就好像没什么大不了的:D –

+0

+1 - 确实非常好。 – DerMike

5

如果抛出更具体的例外情况,则不会阻止任何调用代码在一个Exception catch块中处理所有这些异常。更具体的是更多地记录发生了什么类型的错误,使程序员更容易分开处理它们。

此外,通过抛出“异常”本身,你基本上告诉你的代码的调用者,他们不能排除任何类的异常。一个IOException可能发生,因为可能在NumberFormatException

1

通常你想知道你的应用程序发生了什么,只有在你没有明确定位的异常时,才会捕获特定的异常并让程序失败(或者按照执行顺序更高)。 捕捉异常会捕捉到它们,在某些情况下,您不知道程序失败。

3

一如既往:这取决于。

我认为你暴露给别人的API是有区别的。这可能会活一段时间。在这种情况下,你不知道主叫方认为他的情况最好。

另一方面,总是有你自己内部使用的代码。抛出一个通用的异常可能就足够了。但请记住,您可能稍后要更改一些异常处理。当所有的错误情况一起发生时,这将会更加困难。

0

Dittos to 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无效”?该程序仍然会编译,但不能正常工作。