代码之家  ›  专栏  ›  技术社区  ›  Andy

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

  •  11
  • Andy  · 技术社区  · 16 年前

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

    对于任何一个给定的项目,我想抛出几个不同类型的 例外情况 我不能决定是使用多个子类还是使用具有某种形式的 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 对于发生的任何问题使用特定的枚举类型。我将提供一些机制,以便在任何 MyProject异常 基于类型枚举。

    在项目中处理异常的最好方法是什么,特别是那些共享公共基础设施的项目? 以上两个选项是好的解决方案吗?为什么?为什么?还有什么更好的解决方案呢?

    3 回复  |  直到 16 年前
        1
  •  6
  •   T.J. Crowder    16 年前

    选项2(一个常见的异常+枚举)的主要缺点是您丢失了一些选中异常的实用程序。一个方法必须简单地说“一些与框架相关的事情可能出错”:

    public void foo()
    throws MyFrameworkException
    

    …而不是“X或Y可能出错”:

    public void foo()
    throws SomethingWentWrongException, SomethingElseWentWrongException
    

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

    所以对我来说,像选项1这样的层次结构(如果一个结构表明它自己的话,它不需要非常扁平)是可行的。也就是说,有些人根本不喜欢检查异常,对他们来说,我怀疑上面的说法并不令人信服。-)

    编辑 并且理解了达菲莫的观点:我假设你在谈论你确实必须创造的例外。绝对投掷 标准 任何有意义的地方都有例外(几乎无处不在)。不要创建自己的 MyFrameworkIllegalArgumentException 例如,只需使用 IllegalArgumentException (或其各种子类)。

        2
  •  3
  •   duffymo    16 年前

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

    如果你有那么多特定于业务的例外情况,这会让人感到压抑,这意味着你可能做错了。

    见Joshua Bloch关于 favoring standard exceptions .

        3
  •  1
  •   MicSim    16 年前

    我不会从通用继承 MyFrameworkException ,只要您不在所有项目中提供任何通用的功能。否则,总是扩展异常。

    通常,您应该在域/层边界上抛出有意义的异常。所以关于你的问题,你应该选择1,记住上面的要点。选项2会增加代码复杂性,因为您总是需要检查异常类型以确定出了什么问题。让异常类自己说话。