33

我在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;
}

我想将两个已检查的异常转换为未检查的异常。解决此问题的最佳方法是什么?

我应该只捕获异常并使用捕获的异常作为内部异常抛出一个新的 RuntimeException 吗?

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

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

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

4

4 回答 4

38

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

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

尝试 {
  // 可能抛出异常的代码
} 捕捉(IOException e){
  抛出新的 RuntimeException(e);
} 捕捉(ClassNotFoundException e){
  抛出新的 RuntimeException(e);
}

并且重新抛出RuntimeException的原因将包含在其中。这样,线程顶部的某个人会捕获RuntimeException--您的线程确实会捕获RuntimeException,因此它们不会只是默默地死去,对吗?-- 至少可以打印出原因的完整堆栈跟踪。

但正如其他人所说并将说的那样,检查异常是有原因的。仅当您确定您的客户无法从您作为未经检查的异常重新抛出的问题中恢复时才执行此操作。

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

另请注意,让您的线程捕获 RuntimeException 并至少记录它总是一个好主意。至少这样你就明白为什么你的线程会消失。

于 2009-01-27T19:24:46.337 回答
15

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

  • 调用者代码无法对异常执行任何操作 -> 使其成为未经检查的异常
  • 调用者代码将根据异常中的信息采取一些有用的恢复操作-> 使其成为受检异常

您可能会抛出带有或不带有内部异常的 RuntimeException,这取决于调用者可以用它做什么。如果您不重新抛出内部异常,那么您应该将其记录在您的方法中,如果重要的话。

于 2009-01-27T19:37:59.603 回答
4

您正在以正确的方式进行操作。

为了让已检查的异常在未经检查的情况下通过,您必须将它们包装在未检查的异常中。

请记住,检查异常是有原因的。

于 2009-01-27T19:21:01.510 回答
1

如果你想避免太多try - catch的 es,在工厂本身捕获异常并在那里处理它们。也许返回一个默认实现。

必须在此处或其他地方处理异常。

而且由于这是一个工厂,我认为这些异常最好在工厂本身(相同的方法或不同的方法)中处理,并返回一个默认的实现。

无论如何,(业务功能)调用者在遇到ClassNotFoundException.

于 2009-01-27T19:35:18.360 回答