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


我正在寻求实现我自己的一套 Exceptions 对于我目前正在进行的项目。该项目依赖于具有基本框架异常的核心框架 MyFrameworkException (我也在写这个框架)。

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

在这两种情况下我都有:

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

选项1:


4544
2017-10-14 15:17


起源



答案:


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

public void foo()
throws MyFrameworkException

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

public void foo()
throws SomethingWentWrongException, SomethingElseWentWrongException

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

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

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


6
2017-10-14 15:23



添加到此:选项2看起来像伪装成异常的错误代码。 - Etienne de Martel
是的,计划是永远不要在新的包装异常中重新抛出异常,并且允许某些java / third-party-lib异常在我的项目方法之外传播。我的很多方法都会抛出自定义异常+其他java异常。 - Andy
@Andy:很好,是的,我认为你可能就是这个意思。 - T.J. Crowder


答案:


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

public void foo()
throws MyFrameworkException

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

public void foo()
throws SomethingWentWrongException, SomethingElseWentWrongException

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

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

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


6
2017-10-14 15:23



添加到此:选项2看起来像伪装成异常的错误代码。 - Etienne de Martel
是的,计划是永远不要在新的包装异常中重新抛出异常,并且允许某些java / third-party-lib异常在我的项目方法之外传播。我的很多方法都会抛出自定义异常+其他java异常。 - Andy
@Andy:很好,是的,我认为你可能就是这个意思。 - T.J. Crowder


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

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

请参阅Joshua Bloch的建议 赞成标准例外


3
2017-10-14 15:26



java.lang.Runnable?你的意思是 RuntimeException? - T.J. Crowder
是的,我做到了。走得太快;分心。谢谢你的纠正。 - duffymo


我不会从泛型继承 MyFrameworkException,只要你不提供所有项目共有的任何功能。否则,总是扩展Exception。

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


1
2017-10-14 15:29



MyFrameworkException将具有一些基本功能,并允许我识别/分组源自整个代码套件的异常,因此我仍然希望将其用作基础。 - Andy
我同意Andy的观点 - 除了java.lang基类之外,我认为很少或没有理由扩展任何东西。 - duffymo