自定义异常:通过许多子类或由枚举支持的单个类进行区分?

我希望为我目前正在从事的项目实现我自己的一套。该项目依赖于一个具有基本框架例外的核心框架(我也在编写此框架)。ExceptionsMyFrameworkException

对于任何给定的项目,我想抛出几种不同类型的项目,我无法决定是使用多个子类还是使用某种形式的a作为构造函数参数的单个子类。ExceptionsEnum

在这两种情况下,我都有:

public class MyFrameworkException   extends Exception              { /*...*/ }

选项 1:

public class MyProjectBaseException extends MyFrameworkException   { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }

然后,在整个项目中,我会为发生的任何问题抛出特定的异常。

选项 2:

public class MyProjectException extends MyFrameworkException {
  public static enum Type {
    SpecificType1, SpecificType2, SpecificType3
  }
  public MyProjectException( Type type ) { /*...*/ }
}

在这里,我总是会为发生的任何问题抛出特定的枚举类型。我会提供一些机制,以便可以根据类型枚举对任何语句执行 switch 语句。MyProjectExceptionMyProjectException

处理项目中异常的最佳方法是什么,尤其是那些共享公共基础结构的项目?上述两个选项是好的解决方案吗?为什么或为什么不呢?还有什么更好的解决方案?


答案 1

选项 2(常见异常 + 枚举)的主要缺点是,您丢失了已检查异常的一些实用性。一种方法几乎只能简单地说“与框架相关的某些东西可能会出错”:

public void foo()
throws MyFrameworkException

...而不是“x或y可能会出错”:

public void foo()
throws SomethingWentWrongException, SomethingElseWentWrongException

这意味着可能需要处理一个框架异常的函数必须准备好处理其中任何一个,而如果你是特定的,一个函数只需要准备好处理它调用的框架方法引发的异常。

所以对我来说,像选项1这样的层次结构(如果结构暗示自己,它不必那么扁平)是要走的路。也就是说,有些人根本不喜欢检查异常,对他们来说,我怀疑上述内容不是一个令人信服的论点。:-)

编辑接着duffymo的观点:我假设你说的是你确实必须创造的例外。绝对在有意义的地方抛出标准异常(几乎无处不在)。不要创建自己的,例如,只使用(或其各种子类)。MyFrameworkIllegalArgumentExceptionIllegalArgumentException


答案 2

我会例外地使用描述性类名扩展java.lang.RuntimeException。

如果你有太多特定于业务的例外,这变得压抑,这意味着你可能做错了。

请参阅Joshua Bloch关于支持标准例外的建议。


推荐