【问题标题】:Java Exceptions that cannot be handled无法处理的 Java 异常
【发布时间】:2015-04-03 20:57:03
【问题描述】:

我经常遇到同样的问题。在我的 Java 应用程序的核心,我有一些方法会引发任何方法调用者都无法处理的异常。我必须将这些异常冒泡到 main 方法。所有这些异常总结,所以我在我的应用程序的更高级别上有许多 throws 语句。

例如我的应用程序的核心有一个 NodeJsManager.java 类:

public class NodeJsManager {

    public static void startNodeJs() throws ExecuteException {
        // Code to start NodeJs Server goes here
    }

}

要启动 NodeJs 服务器,我必须在命令行上执行一些操作。我可以用 apache 类 org.apache.commons.exec.CommandLine 做到这一点。但如果执行以错误代码退出,则会引发 ExecuteException。如果没有启动 NodeJ,我的应用程序将毫无用处。没有任何方法可以捕获此异常,这只是我的应用程序工作的要求。所以这个异常几乎会在整个应用程序生命周期中冒泡。我有其他执行相同操作的管理器(如果配置路径错误,则 ConfigurationManager 会引发异常)。总之,它在更高级别的每个方法中总结了许多 throws 语句,我什至不记得该异常的原因。

你会如何处理这个问题?我必须做一些完全错误的事情,因为我找不到描述我的问题的类似帖子!

问候 迈克

更新

我刚刚发现了我的旧 Effective Java 书。作者(Google 的一名 Java 架构师)写了以下关于异常的文章:

...对可恢复条件和运行时使用检查异常 编程错误例外。

...

如果不清楚是否可以恢复,最好使用未经检查的异常...

在我的情况下,它显然是不可恢复的,所以抛出运行时异常是要走的路。我一直认为应该防止运行时异常,这改变了我对 Java 异常的看法。

【问题讨论】:

    标签: java exception


    【解决方案1】:

    一种可能的方法是处理Exception 尽可能靠近它的起源地,在那里你有足够的信息来决定要做什么。

    正如您所说,如果您将所有Exceptions 捕获在最高级别,您将失去非常重要的上下文,因为这提供了有关问题发生原因和方式的信息(并希望有一些解决方法它)。

    例如,您说没有 NodeJS 服务器的应用程序是无用的,那么这样做的一种方法可能是让NodeJSManager(如果存在这样的事情:D,我猜)不抛出,但完全阻止应用程序启动,例如

    NodeJSManager nodejsManager = new NodeJSManager();
    boolean succeeded = nodejsManager.tryToStart();
    if (!succeeded) {
        // guard, it's useless to proceed
        // cleanup and exit
    }
    

    我称该方法为tryToStart,因为它可能会发生服务器无法启动的情况,您正在直接处理可执行文件和文件系统,所以我会说这不再那么例外(但可能这只是一个口味问题)。

    恕我直言,重要的是您将应用程序启动指定为一系列检查,例如节点和配置检查,而无需处理 Exceptions 来处理代码流。

    【讨论】:

      【解决方案2】:

      我不喜欢检查异常。我用来做的(但不是一个好的解决方案)是捕获检查的异常并以这种方式将其作为运行时异常重新抛出:

      catch (ExecuteException e) {
          throw new RuntimeException (e);
      }
      

      检查的异常“e”作为参数传递给 RuntimeException。这样,我将已检查的异常转换为未经检查的异常。但正如我所说,这不是一个好的解决方案,它可能会导致它解决的更多调试问题。当“检查”异常时,往往是因为描述的错误是“严重的”。

      【讨论】:

        【解决方案3】:

        一种解决方案是创建您自己的更通用的异常类,该类将扩展Exception 并将未处理的异常作为原因包装到您自己的异常中。这样,您至少可以减少方法签名中的一些异常。示例:

        创建新类StartupExceptionConfigurationException 并在启动阶段将其捕获为原因后将其与主要异常一起抛出。

        此外,如果您要创建StartupException extends RuntimeException),则不必声明此类例外。

        另一种方法是将所有内容包装到RuntimeException

        如果 abowe 不符合您的需求,这可能是设计缺陷,(如果您真的无法处理)您将不得不处理它。

        【讨论】:

          猜你喜欢
          • 2015-05-21
          • 1970-01-01
          • 1970-01-01
          • 2013-09-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-02
          相关资源
          最近更新 更多