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

如何在Java中定义自己的异常层次结构,以及在何处定义?,java,exception,try-catch,Java,Exception,Try Catch,如何在Java中定义自己的异常层次结构,以及在何处定义 我的主要问题涉及必须在其中定义异常类的包位置 我们是否为我们的异常创建一个特殊的包并将所有类放在其中?该语言没有规定用户定义的异常类应该放在哪些包中的任何要求。只要类扩展了java.lang.Throwable,就可以抛出它。您可以在任何地方创建异常类 重要的是扩展现有的异常类(java.lang.Throwable)。例如java.lang.Exception或java.lang.RuntimeException。第一个是选中的异常,而扩

如何在Java中定义自己的异常层次结构,以及在何处定义

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


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

该语言没有规定用户定义的
异常
类应该放在哪些包中的任何要求。只要类扩展了java.lang.Throwable,就可以抛出它。

您可以在任何地方创建异常类


重要的是扩展现有的异常类(
java.lang.Throwable
)。例如
java.lang.Exception
java.lang.RuntimeException
。第一个是选中的异常,而扩展RuntimeException将导致未选中的异常;两者之间的区别是详细的。

我将此作为一般规则

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

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


我的理由是:如果一个给定的异常只在某个地方的一个或两个服务类中出现,那么它可能不是一个足够普遍的异常,不值得拥有自己的类。只有当我看到一个公共主题出现在多个地方时,我才会麻烦地创建一个自定义异常类。如果它出现在多个地方,那么就没有逻辑包可以“附加”到它,因此特定于异常的包似乎是正确的选择。

要回答主要问题

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

我不鼓励这样做

什么是包裹,

包是一个名称空间,它组织了一组相关的类和接口。从概念上讲,您可以认为软件包类似于计算机上的不同文件夹。您可以将HTML页面保存在一个文件夹中,将图像保存在另一个文件夹中,将脚本或应用程序保存在另一个文件夹中。因为用Java编程语言编写的软件可以由成百上千个单独的类组成,通过将相关的类和接口放入包中来保持组织是有意义的

自定义异常也是一个Java类。它应该在其他相关的类和接口之间进行组织。这种关联性不应该基于它是否是一个例外来决定,而应该基于它正在做什么,或者它存在的目的来决定

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

public class EmployeeRecordNotFoundException extends Exception {
    // constructors ... etc ...
}
然后,您可以将该类与要使用它的类放在同一个包中

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
com.abc\u org.management.employee\u management
雇员雇员薪酬调查员
新雇员创造者
EmployeeRecordNotFoundException//将其放在其所属位置

EmployeeIDValidator//我想询问者已经意识到了这一点。他的问题更多地与最佳实践相关。
我有一个a.b.c.BusinessException要处理。
这是什么意思?你能说清楚一点吗?一种意思可能是您在包
a.b.c
内创建名为
BusinessException
Exception
。另一种含义是在包
a.b.c
内创建名为
BusinessException
的包。然后在包
a.b.c.BusinessException
中创建异常。定义自己的包方案。我将为它们创建一个com.foobar.exceptions包(使用com.foobar)并由您自己的默认值替换。