gpt4 book ai didi

java - 服务层中的已检查异常与未检查异常

转载 作者:太空狗 更新时间:2023-10-29 22:44:28 29 4
gpt4 key购买 nike

我在一个带有旧服务层的项目上工作,如果请求的记录不存在,或者由于调用者未得到授权而无法访问,则在很多地方返回null。我说的是ID要求的特定记录。例如,类似:

UserService.get(userId);

最近,我一直在努力更改此API,或者用引发异常的新API进行补充。随之而来的是关于检查与未检查异常的争论。

从JPA/Hibernate等所有设计师的笔记中,我建议未检查的异常可能是最合适的。我的观点是,不能合理地期望API用户从这些异常中恢复,并且在99%的情况下,我们最多只能通知应用程序用户发生了一些错误。

将运行时异常传播到通用处理机制显然会减少很多复杂性,并减少处理边缘情况异常所需的分支处理。但是,围绕这种方法有很多担忧(正确地如此)。

为什么诸如JPA/EJB和Hibernate之类的项目的设计人员选择使用未经检查的异常模型?有很好的理由吗?有什么优点/缺点。使用这些框架的开发人员是否应该仍在处理运行时异常,例如使用适配器包装程序抛出异常的地方?

我希望这些问题的答案可以帮助我们针对自己的服务层做出“正确”的决定。

最佳答案

尽管我同意未经检查的异常可以使API更加方便的观点,但我认为这并不是最重要的好处。而是这样的:

抛出未经检查的异常可以帮助您避免严重的错误。

这就是为什么。考虑到十个开发人员被迫处理受检查的异常,您将获得二十种不同的策略来处理它们,其中许多是完全不合适的。以下是一些较常见的错误方法:

  • 吞下。 捕获异常并完全忽略它。即使应用程序现在处于不稳定状态,也可以继续进行,好像什么都没发生。
  • 记录并吞下。 捕获异常并记录下来,以为现在我们要负责了。然后继续前进,好像什么也没发生。
  • 默认为“神秘”。 捕获异常,然后将某些字段设置为某些默认值,通常无需告知用户。例如,如果您无法加载某些用户角色,则只需选择一个低特权角色并进行分配即可。用户想知道发生了什么。
  • 愚蠢/危险的神秘预设。 捕获异常,并将某些字段设置为某些非常差的默认值。我在现实生活中看到的一个示例:无法加载用户的角色,因此继续努力并发挥最佳作用(即,给他们提供高特权角色,以免给任何人带来不便)。
  • 错误报告。 开发人员不知道异常的含义,因此只提出自己的想法。即使建立连接与该问题无关,IOException也会变为“无法连接到服务器”。
  • 通过广泛捕获掩盖和误报。 尝试通过捕获Exception或(ugh)Throwable而不是方法实际引发的两个检查的异常来清理代码。异常处理代码不会尝试将资源可用性问题(例如IOException)与直接代码错误(例如NullPointerException)区分开。实际上,它经常会任意选择一个异常(exception),并将每个异常(exception)都错误地报告为此类异常(exception)。
  • 通过大量尝试蒙版,并误报。 先前策略的一种变体是将一大堆异常声明调用放在单个大try块的范围内,然后捕获ExceptionThrowable,因为没有别的方法可以处理所有引发的异常。
  • 抽象-不正确的重新抛出。 即使该异常不适合抽象,也要抛出该异常(例如,从应该隐藏资源的服务接口(interface)中抛出与资源相关的异常)。
  • 重新包装而不包装。 抛出一个异常(未经检查或抽象适当的检查),但只需删除嵌套的异常,该异常将使任何人都有机会真正了解正在发生的事情。
  • 戏剧性的 react 。 通过退出JVM响应非致命异常。 (感谢this blog post。)

  • 以我的经验,看到上面的方法比看到正确的响应要普遍得多。许多开发人员-甚至是“高级”开发人员-都具有必须不惜一切代价抑制异常的想法,即使这意味着在不稳定的状态下运行该应用程序。这是危险的错误。

    未经检查的异常有助于避免此问题。不知道如何处理异常的开发人员倾向于将异常视为要克服的不便之处,并且他们不会全力以赴地捕捉异常。因此,异常只会冒泡地到达顶部,在那里它们提供了堆栈跟踪,并且可以以一致的方式对其进行处理。在极少数情况下,实际上要做的事要比使异常冒出来要好得多,没有什么可以阻止您。

    关于java - 服务层中的已检查异常与未检查异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6591470/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com