自定义异常:通过许多子类或使用enum支持的单个类进行区分?

时间:2010-10-14 15:17:12

标签: java exception exception-handling custom-exceptions

我正在为我正在进行的项目实施我自己的Exceptions集。该项目依赖于具有基本框架异常MyFrameworkException的核心框架(我也在编写此框架)。

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

在这两种情况下我都有:

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 ) { /*...*/ }
}

对于发生的任何问题,我总是将MyProjectException与特定的枚举类型一起抛出。我提供了一些机制,以便可以根据类型枚举在任何MyProjectException上执行switch语句。

处理项目中的异常的最佳方法是什么,尤其是那些共享公共基础架构的方法?这两个选项是否优于良好的解决方案?为什么或者为什么不?什么是更好的解决方案?

3 个答案:

答案 0 :(得分:6)

选项2(一个常见的例外+枚举)的主要缺点是你失去了一些检查异常的效用。一种方法几乎不得不简单地说“框架相关的东西可能会出错”:

public void foo()
throws MyFrameworkException

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

public void foo()
throws SomethingWentWrongException, SomethingElseWentWrongException

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

所以对我来说,选项1之类的层次结构(如果结构表明自己,它不需要那么平坦)是要走的路。也就是说,有些人根本不喜欢经过检查的例外情况,对我们来说,我怀疑上述内容并不是一个引人注目的论点。 : - )

编辑并接受duffymo的观点:我假设你在谈论你真正必须创建的异常。绝对抛出标准例外的地方(几乎无处不在)。不要创建自己的MyFrameworkIllegalArgumentException,例如,只使用IllegalArgumentException(或其各种子类)。

答案 1 :(得分:3)

我会使用描述性类名扩展java.lang.RuntimeException的异常。

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

见Joshua Bloch关于favoring standard exceptions的建议。

答案 2 :(得分:1)

我不会从通用MyFrameworkException继承,只要你不提供所有项目共有的任何功能。否则,总是延长Exception。

通常,您应该在域/层边界处抛出有意义的异常。所以关于你的问题,你应该选择1,考虑到上述要点。选项2会增加代码复杂性,因为您始终必须检查异常类型以确定出错的地方。让异常类说明一切。