在 Java 中将已检验的异常包装到未选中的异常中?

2022-09-01 08:40:32

我在java中有这个工厂方法:

public static Properties getConfigFactory() throws ClassNotFoundException, IOException {
    if (config == null) {
        InputStream in = Class.forName(PACKAGE_NAME).getResourceAsStream(CONFIG_PROP);
        config = new Properties();
        config.load(in);
    }
    return config;
}

我想将两个选中的异常转换为未选中的异常。最好的方法是什么?

我是否应该只捕获异常并使用捕获的异常作为内部异常来引发新的运行时异常?

有没有更好的方法来做到这一点,或者我甚至应该首先尝试这样做?

编辑:
只是为了澄清。这些异常将是致命的,因为配置文件本质上是程序的操作,所有异常都将被捕获并记录在我的程序的顶层。

我的目的是避免不必要的抛出异常,将异常添加到调用我的工厂的每个方法的签名中。


答案 1

仅当客户机无法从任何问题中恢复时,才应使用 A。偶尔做你正在谈论的事情是合适的,但更常见的是它不合适。RuntimeException

如果您使用的是 JDK >= 1.4,则可以执行以下操作:

try {
  // Code that might throw an exception
} catch (IOException e) {
  throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
  throw new RuntimeException(e);
}

并且重新抛出将包含原始原因。这样,线程顶部的某个人就会捕捉到 - 你的线程确实会捕获,这样它们就不会默默地死去,对吧?-- 至少可以打印出原因的完整堆栈痕迹。RuntimeExceptionRuntimeExceptionRuntimeException

但正如其他人已经说过并且会说的那样,检查例外情况是有原因的。仅当您确定客户端无法从您作为未检查的异常重新引发的问题中恢复时,才执行此操作。

注意:如果可用,最好使用更具体的未经检查的异常。例如,如果您的方法可以抛出 的唯一原因是因为缺少配置文件,则可以重新抛出 a ,这是一个未经检查的异常,但会提供有关抛出它的原因的详细信息。如果它们描述了您要重新抛出的问题,则使用的其他好方法是,和。RuntimeExceptionClassNotFoundExceptionMissingResourceExceptionRuntimeExceptionIllegalStateExceptionTypeNotPresentExceptionUnsupportedOperationException

另请注意,线程捕获 RuntimeException 并至少记录它始终是一个好主意。至少通过这种方式,您可以理解为什么线程会消失。


答案 2

关于异常处理最佳实践的两点:

  • 调用方代码无法对异常执行任何操作 ->使其成为未选中的异常
  • 调用方代码将根据异常 ->使其成为选中的异常中的信息执行一些有用的恢复操作

您可以抛出运行时异常,无论是否具有内部异常,具体取决于调用方可以对其执行的操作。如果您没有重新抛出内部异常,那么您应该将其记录在您的方法中(如果很重要)。