Java 每件事都有特定的例外情况是一种好的做法吗?还是重用更抽象的异常更好?

Java 每件事都有特定的例外情况是一种好的做法吗?还是重用更抽象的异常更好?,java,exception-handling,Java,Exception Handling,我正在处理一个项目,在这个项目中,我为每个可能的异常情况编写了一个异常。关键是我发现它更“可读”,但我得到了大量不同的例外 这样做被认为是一种好的做法吗?或者我应该把异常写得更抽象一点,这样就不会有那么多异常了 非常感谢您的时间。为什么不创建少量异常并让它们在构造函数中使用描述性字符串呢 throw new GenericException("Error: problem with...."); 并让toString()方法打印出传递给它的字符串。哪个更好取决于代码捕获特定异常的可能性。如果您

我正在处理一个项目,在这个项目中,我为每个可能的异常情况编写了一个异常。关键是我发现它更“可读”,但我得到了大量不同的例外

这样做被认为是一种好的做法吗?或者我应该把异常写得更抽象一点,这样就不会有那么多异常了


非常感谢您的时间。

为什么不创建少量异常并让它们在构造函数中使用描述性字符串呢

throw new GenericException("Error: problem with....");

并让toString()方法打印出传递给它的字符串。

哪个更好取决于代码捕获特定异常的可能性。如果您只可能捕获(或以其他方式区分)更一般的(超类)异常,那么拥有更多更具体的(子类)异常就不会有多大效果。在这种情况下,最好定义更少的异常,并使用异常消息来表达错误的更详细信息

另一方面,如果已经存在特定的异常,那么使用它们是有意义的。在我看来,仅仅抛出
java.lang.Exception
java.lang.RuntimeException
是非常懒惰的

跟进


我总是捕获特定的异常,但问题是,在其他“捕获”中,我也使用类似的特定异常(例如,它们可以引用“数据库”,但它们不同)。所以问题是,做一个“DatabaseException”并使用它是否是一件好事,而不是像“DatabaseConnectionException”和“DatabaseDataException”,它更具可读性,但最终我得到了数百万个显式异常

如果您的代码经常如下所示:

try {
    ... 
} catch (DatabaseConnectionException ex) {
    // do something
} catch (DatabaseDataException ex) {
    // do same thing
} catch (DatabaseTangoException ex) {
    // do same thing
}
try {
    ... 
} catch (DatabaseConnectionException ex) {
    // do something
} catch (DatabaseDataException ex) {
    // do something completely different
} catch (DatabaseTangoException ex) {
    // do something totally extraordinary
}
。。。那么您的细粒度异常就没有帮助了。但如果是这样的话:

try {
    ... 
} catch (DatabaseConnectionException ex) {
    // do something
} catch (DatabaseDataException ex) {
    // do same thing
} catch (DatabaseTangoException ex) {
    // do same thing
}
try {
    ... 
} catch (DatabaseConnectionException ex) {
    // do something
} catch (DatabaseDataException ex) {
    // do something completely different
} catch (DatabaseTangoException ex) {
    // do something totally extraordinary
}
。。。那么,您的细粒度异常可能正在为您工作。如果您将这三个异常声明为
DatabaseDataException
的子类,那么您可以根据情况一起或分别处理这些情况


实际上,这取决于您在应用程序的上下文中做出自己的判断。

我认为在可能的情况下有特定的例外情况是一种好的做法

按照这种做法,我们会根据异常类型给出不同的错误消息

甚至像Java这样的编程语言也支持这个概念,允许程序员扩展异常类并创建自己的异常子类

你也可以从下面的问题中获得更多信息。

我建议使用一个抽象的DomainException(其中domain反映了问题所在的组织或应用程序层),您的所有特定异常都会扩展它

然后,您可以捕获DomainException来说明这是您的代码的问题,然后根据需要进行优化。

:

第60项:赞成使用标准例外

重用先前存在的异常已经很困难了 有几个好处。其中最主要的,, 它使您的API更易于学习和使用 使用,因为它与已建立的 程序员所遵循的约定 已经很熟悉了。紧随其后的是 使用API的程序是 更容易阅读,因为它们不是 充斥着不熟悉的例外情况。 最后(也是最不重要的),更少的异常 类意味着更小的内存 占用空间和更少的加载时间 上课


您可以扩展异常并不意味着您应该这样做。Dogbane的答案为使用标准异常提供了很好的理由。(请注意,他说的是使用“标准”异常,而不是“通用”!请使用您可以找到的特定标准异常。)

我认为,只有当这两个条件都满足时,才应该使用自己的异常子类:

  • 当捕捉到某类异常时,您希望做一些特定的事情;在这种情况下使用特定的子类可以让您捕获它,同时让其他异常毫无问题地出现
  • 没有任何标准的例外情况能够足够准确地涵盖您的类别

我总是捕获特定的异常,但问题是,在其他“捕获”中,我也使用类似的特定异常(例如,它们可以引用“数据库”,但它们不同)。所以问题是,做一个“DatabaseException”并使用它是否是一件好事,而不是像“DatabaseConnectionException”和“DatabaseDataException”,它更具可读性,但最终我得到了数百万个显式异常。@raspayu我和stephen一起去,仅创建一个与域相关的异常,并为每种类型的错误指定详细消息。始终扩展运行时异常。阅读有效的java以了解用法。@Raspayu使用继承。创建DatabaseException并让DatabaseConnectionException扩展它。这样你就可以在需要处理DatabaseException时捕获它们,或者在需要特定处理程序时捕获特定的异常。我总是“做一些完全不同和不同寻常的事情”,呵呵。只是开玩笑,但是的,每个例外都需要不同的处理,所以看起来我做得很好。谢谢:-)@Joeri是的,看起来很棒。将从现在开始使用它!是的,这正是问题所在,这是最佳实践:许多不同的自描述性异常,或者只有少数异常可以从发生的事情中向您提供错误消息?这简直是邪恶()。使异常可扩展的全部意义在于,您可以捕获要处理的异常,而忽略其他异常。当您扩展异常时,客户端会感到痛苦,当您编写api库时,客户端会被迫重新抛出或处理异常。当连我们的API类都不知道该做什么并抛出它时,客户端如何处理exte