如果我要抛出包装器异常,在Java中包装低级异常的目的是什么?

时间:2011-07-05 20:19:11

标签: java exception exception-handling

我理解抛出特定于您所在的应用程序层的异常,但是如果您是以下所有这些异常处理开销的目的是什么:

  1. 只是让例外气泡升到顶端。
  2. 永远不要对包装的例外做任何“独特”。
  3. 例如,我有一个抛出SQLException的DAO,而下一层是一个调用DAO的管理器。普遍接受的范例是我创建一个管理器异常,包装我的SQLException,然后抛出管理器异常。为什么?如果链上的另一个类无论如何要处理它,那么为什么要包装呢?

8 个答案:

答案 0 :(得分:10)

在您的示例中,它可能没用。但是假设您正在编写具有许多可能实现的接口。例如,假设从现在起两年后,您将从SQL数据库切换到NoSQL数据库。然后,您的DAO将被强制声明NoSQLException,并且必须重写所有调用代码。如果SQLException或NoSQLException包含在您的自定义异常中,则调用代码可以保持不变。

答案 1 :(得分:4)

在您的特定示例中,如果您有一个调用DAO的服务层,则不希望客户端看到SQL异常,例如“ORA-00118:违反了唯一约束(BLABLA)”。

使这些异常消息对高级层有意义是您考虑将它们包装到更有意义的异常中的一个原因。

答案 2 :(得分:3)

如果要向其中添加一些有用的信息,或者使其特定于您的域,则应该只包装并抛出异常。否则你应该让异常泡泡到可以处理的地方。我猜你正在为你的例子看一些可疑的代码。

包装异常(可能实际上有用)的一个示例是将特定于实现的异常“转换”为IoC / DI场景中更具体的框架。例如,如果你有一个框架可以做一些工作,你想要保护客户端代码不必“知道”一堆特定的异常。因此,您创建了一组常见的异常,您的插件会抛出这些异常并且您的客户端代码知道并可以处理。就像一堆不同后端的数据访问异常一样。

答案 3 :(得分:3)

捕捉和重新投掷不处理任何事情。在这种情况下,最好让它冒泡。

捕获已检查的异常并重新投掷为未选中可能是一件有用的事情,但最好添加更具体的信息。

答案 4 :(得分:1)

java强制您明确声明可以抛出哪些异常。包装异常阻止:
1。揭示您的具体实现(较高级别可能不知道您使用sql作为数据库,因此您可以抛出MyAppException)。
2。否则,声明的例外列表会增加加班时间,这将强制执行更高级别来处理所有这些,这可能不是很整洁。

答案 5 :(得分:0)

我认为这完全取决于您希望的具体程度以及是否要在自定义例外中包含更多信息。否则,您可以允许其他方法抛出的异常冒泡并按您认为合适的方式处理它们。

在您的情况下,SQLException可能过于通用,因此将其包装在您自己的自定义异常中可以帮助您更轻松地确定在应用程序中抛出它的位置并包含更多特定信息。

答案 6 :(得分:0)

因此,使用不同数据存储的DAO的不同实现可以将不同的特定于存储的异常转换为相同的抽象存储异常。然后他们只是包含原件用于调试目的。

答案 7 :(得分:0)

我建议在许多情况下,通过将异常减少到三种类型来最有效地处理异常:

OperationFailedStateOkException
操作无法完成,但本地和全局系统状态是可以的,除非该失败隐含的程度(例如,尝试引用字典中不存在的项目)。
OperationFailedLocalStateCorruptException
操作无法完成,并且本地系统状态已损坏(例如,尝试从损坏的词典中引用项目)。
OperationFailedGlobalStateCorruptException
操作无法完成,全局系统状态已损坏(例如共享缓存已损坏)。

请注意,在许多情况下,例程的调用者对失败的原因几乎不会感兴趣,因为失败意味着系统的状态。如果程序员知道它们可能发生的原因以及如何处理它们,则通常可以安全地捕获第一类型的异常并恢复执行。在某些情况下,它们可能需要作为第二种类型的异常重新抛出(例如,如果系统无法执行某些操作,而这些操作对于维护数据结构的一致性是必要的)。第二种类型的那些只应被捕获并作为第一种类型在腐败状态将被放弃的级别上重新抛出(例如,“加载文档”例程可能捕获此类异常并重新抛出为“状态正常”异常(如果有的话)尝试加载文档失败时使用的损坏数据结构将被丢弃。那些第三种类型通常应该触发程序关闭。

可以肯定的是,在不同类型之间进行一些渐变可能是有用的(例如,指示应该轻轻关闭程序的全局问题,保存用户数据,而不是表明事情是如此糟糕以至于试图保存用户数据会腐败的事情更糟)。尽管如此,捕获异常并重新抛出表示系统状态的异常可能比仅仅留下更高级别的代码以了解如何处理InvalidArgumentException更好。