在Java库中抛出异常的最佳实践

3
我正在开发一个JAR库用于数据库访问。我首先捕获了try块中发现的所有异常并处理它们。但后来,我认为更好的做法是将异常抛给最终程序员来捕获和处理,因为它是一个库。
关于处理JAR文件中的异常,最佳实践是什么?
以下是我的JAR的示例代码,你可以看到有许多异常被抛出。这是一个好的做法还是有更好的方法?(比如定义一个新的自定义异常;如果是这样,如何做到?)非常感谢任何关于此的帮助。
 public static NConnection getNConnection(String path) throws IOException, ParserConfigurationException, SAXException {

    NConfigurations conf = new NConfigurations();
    conf.setConfigurationLoc(path);
    String dbPath = conf.getDatabasePath();
    return createConnection(dbPath);
}

“处理 JAR 文件中的异常” 究竟是什么意思? - Maroun
定义自定义异常很容易:public class CustomException extends Exception{} - ByteHamster
我正在编写一个用于数据库访问的Java库,想知道在方法签名中抛出异常还是在try-catch块中处理异常哪种方式更好。 - ndnine89
首先,你应该了解检查异常和运行时异常之间的区别。如果路径是由库用户提供的,当文件在路径中不存在时,他/她需要捕获异常。同样,如果文件不符合预期格式,也需要捕获异常。也就是说,在你的情况下,你应该抛出所有的错误。这是我的观点... - sgpalit
谢谢,根据您的建议,由于这里抛出的所有三个异常都是Checked异常,我必须将它们抛出并要求最终程序员处理。 - ndnine89
4个回答

1
您可以采用两种方式:抛出原始异常或将其嵌套在自定义异常中。这是一个设计决策。
通常,抛出与代码功能相关的异常是有意义的。例如,如果进行I/O操作,则会出现IOException,因为这是可能由i/o操作引起的自然问题。
在您的情况下:这取决于NConnection抽象的内容。如果不公开IOException,那么可能没有意义,因为它是具体实现的。您可以创建自己的应用程序特定异常并包装io异常:
try {
   // code that throws i/o exception 
} catch (IOException ioe) {
   throw new NException("Something went wrong", ioe);
}

1
这个问题并没有简单的答案, 社区对于到底使用哪种方式最好还没有定论。简而言之,如果你想要强制调用者处理某些出错情况/给他从异常状态中恢复的机会,那么可以使用checked exceptions。对于其他情况,如违反约定等编程错误,则需要使用runtime exceptions
在我看来,任何库都应该扩展其自己的异常类,即使仅仅是包装原始的异常。这样,作为客户端,我就可以阅读堆栈跟踪,并轻松发现我的代码的哪一部分出了问题。例如,如果有一个DBFrameworkException,这比常见的NullPointerException更清晰。
此外,参考Bloch 的 Effective Java 条目58,获取更好的解释。

示例代码中抛出的所有三个异常都是已检查的。抛出多个异常让最终程序员处理是否可以?还是在良好的设计原则中被看作是不可取的? - ndnine89
我不建议这样做,因为它会大大增加调用者代码的大小。这并不是真正的糟糕设计,只是作为客户端使用起来很麻烦。 - LastFreeNickname
谢谢您的建议,我会将这三个异常封装在一个“DBFrameworkException”中并抛出,以便用户知道出了什么问题和在哪里。 - ndnine89

1
在我看来,你应该捕获所有底层异常,例如方法签名中的异常(例如IOException),然后如果需要,使用你认为合适的消息和类型抛出自定义异常。
这样做的原因与良好的编程实践有关,你可能希望用之前使用的库(例如jdbc驱动程序)替换某些东西。当导入新版本时,你不希望用户代码在MySQL重复键错误时中断,而可以使用通用的重复键异常。

1

我认为抛出异常是更好的方式,因为使用该jar包的人可以在Java类中处理这些异常。就像DriverManage.getConnection()抛出ClassNotFoundException一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接