在Java中如何以及在何处定义自己的Exception层次结构?

时间:2010-04-21 13:18:17

标签: java exception try-catch

在Java中如何以及在何处定义自己的Exception层次结构?

我的主要问题涉及必须定义异常类的包位置。

我们是否为异常创建了一个特殊的包并将所有类放在其中?

5 个答案:

答案 0 :(得分:28)

我将此作为一般规则使用。

  • 如果有意义,请使用预定义的Java异常。例如,如果您的代码有某种I / O错误,则可以抛出IOException。
  • 如果需要区分try / catch块中的两个异常,则仅使用异常层次结构。很多时候,让单个组件抛出一个异常类型,并针对不同的错误使用不同的消息是完全正确的。如果用户无法真正做任何事情来专门处理错误,请使用相同的通用异常类。如果用户能够以不同方式处理它们,那就是应该使用层次结构。
  • 对于层次结构,不要使来自不同组件的所有异常都从基本异常继承。没有真正的理由这样做。如果消费者想抓住任何东西,他们就可以捕捉到异常。
  • 对于包位置,我将Exception类与其相关的代码放在一起。因此,如果我在一个包a.b.c中有一个BusinessService,那么我有一个a.b.c.BusinessException。我不喜欢将所有异常放入异常包中。它只是很难找到。

答案 1 :(得分:12)

我将所有自定义异常放入com.company.project.exception包中。我这样做,而不是把它们“靠近”它们出现的位置。

这是我的推理:如果给定的异常仅在一个或两个服务类中出现,那么它可能不是一个足够的例外来配置它自己的类。只有当我看到在多个地方弹出一个共同的主题时,我才会遇到创建自定义Exception类的麻烦。如果它出现在多个地方,那么没有逻辑包来“附加”它,所以特定于异常的包似乎是正确的方法。

答案 2 :(得分:5)

您可以随时随地创建您的异常类。

重要的是扩展现有的Exception类(实际上是java.lang.Throwable)。例如java.lang.Exceptionjava.lang.RuntimeException。第一个是检查异常,而扩展RuntimeException将导致未经检查的异常;两者之间的差异详细here

答案 3 :(得分:1)

该语言没有为应该放入用户定义的Exception类的包指定任何要求。只要类扩展java.lang.Throwable,就可以抛出它。

答案 4 :(得分:0)

要回答主要问题,

问:我们是否为异常创建一个特殊的程序包并将所有类放入其中?

我不鼓励这样做。

什么是软件包as it says in the Oracle docs

包是 组织一组相关类和接口 的命名空间。从概念上讲,您可以将软件包视为类似于计算机上的不同文件夹。您可以将HTML页面保留在一个文件夹中,将图像保留在另一个文件夹中,并将脚本或应用程序保留在另一个文件夹中。由于用Java编程语言编写的软件可以由成百上千个单独的类组成,因此 通过将相关的类和接口放入程序包中使事情井井有条是很有意义的。 / p>

自定义异常也是Java类。并且应该在其他相关的类和接口之间进行组织。不应基于它是否是异常来确定其相关性,而应该基于它在做什么或它的存在目的来确定其相关性。

例如,假设您在管理系统中工作,并且拥有一个处理后端API来检索员工记录的软件包。如果您无法检索到给定员工ID的记录,并且如果您有特殊需要在层次结构中处理此特定方案,则可以定义一个自定义异常EmployeeRecordNotFoundException。

public class EmployeeRecordNotFoundException extends Exception {
    // constructors ... etc ...
}

然后,您可以将该类放在与要使用它的Class相同的程序包中。

com.abc_org.management.employee_management
    EmployeeDetailsRetriever
    NewEmployeeCreater
    EmployeeRecordNotFoundException // place it where it belongs
    EmployeeIDValidator  // <- TIP : don't make utility classes as well, make class that do the utility function and make that class do only that specific thing
com.abc_org.management.customer_management
    // no class in here is going to use EmployeeRecordNotFoundException
    // so no point of making that available to this as well
com.abc_org.management.exception
    // no point of creating this

在更全局的级别上对其进行定义没有任何意义,因为没有其他类可以访问它。