有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

编写Java库(不是应用程序)时如何处理异常

我目前正在为RESTful web服务API编写Java包装器

我现在正试图清理一些异常处理,但不确定采取什么方法。这是一个供Java程序员使用的工具,因此我不能像处理最终用户应用程序那样处理它

如果我有一个方法(连接),其中包含可能引发异常的代码,那么如何让这些异常浮起到最终程序员?这就是我应该处理它的方式吗,取决于它们捕获异常?等等


共 (5) 个答案

  1. # 1 楼答案

    我认为API做什么以及在什么上下文中使用它很重要

    如果API是表示/呈现层的一部分,那么我更愿意始终返回准备好呈现、修饰或写入响应流的内容

    如果API要执行(非呈现/UI相关的)处理,我就可以抛出超出API逻辑范围的任何异常

    如果API设计得很好,那么这些原因显然超出了API的控制范围,或者逻辑上超出了API“知道如何”或“应该”处理的范围,即使它可以捕获/控制它

    当向“用户”返回异常时,我更喜欢尽可能返回标准异常,而不是单一的自定义包装类型

    然而,在我的API实现中,如果自定义异常类型有明确和有用的用途,我会经常使用它们

    就我的2美分:)

  2. # 2 楼答案

    问题是你希望你的图书馆有多不透明

    您向用户抛出的每一种异常类型都应该暗示用户可以对此做些什么。比如说,

    catch (ConnectionException e) {
      disconnect();
      connectAgain();
    }
    

    仅当您的用户有权断开()和再次连接()。但是,如果您承诺提供所有类型的连接,那么您的代码应该已经有了这种逻辑,如果失败了,抛出一个通用的WrapperException并处理它

    对于您来说,一个好的方法可能是声明您自己的异常类型(不要将其设置为RuntimeException),捕获您观察到的异常并抛出您的异常

  3. # 3 楼答案

    我认为您应该决定现有类型是特定于实现的,还是库固有的。例如,如果它是一个与网络相关的异常,而您显然正在制作一个基于网络的API,我就让它传播起来。无论如何,调用方都需要知道这种错误

    另一方面,如果它是一个与数据库相关的异常,这只可能是因为出于某种奇怪的原因,您正在嵌入式数据库中查找WSDL,或者类似的东西,这显然不适合调用方处理——因此,捕获它并将其封装在更适合您的抽象级别的异常中

  4. # 4 楼答案

    在任何情况下,您都必须将异常传递给用户,因为它是一个库

    • 如果您没有日志记录,也不打算创建自定义异常,那么您就不必处理异常
    • 如果正在记录,请处理异常并重新显示异常
    • 如果您有自定义异常,请确保它具有takeexception构造函数参数,然后将当前异常链接到当前异常,然后抛出自定义异常。这是维护有用的堆栈跟踪信息所必需的
  5. # 5 楼答案

    我建议您从底层API捕获异常(除非它们真的允许通过),并抛出一个更适合您的抽象级别的新异常

    如果不想放弃异常的原因,请使用exception chaining