我经常遇到同样的问题。在我的Java应用程序的核心,我有一些抛出异常的方法,任何方法调用者都无法处理。我必须将这些异常搞砸到main方法。所有这些异常总结,所以我在我的应用程序的更高级别上有很多抛出语句。
E.g。我的应用程序核心有一个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中异常的看法。
答案 0 :(得分:1)
一种可能的方法是尽可能接近Exception
来处理它所在的位置,在那里你有足够的信息来决定做什么。
正如你所说的,如果你所有的Exception
都被捕获到最高级别,你就会失去真正重要的上下文,因为这会提供有关问题发生原因和方式的信息(希望有几种方法)解决它。)
例如,您说没有NodeJS服务器的应用程序是无用的,那么可能这样做的方法是让NodeJSManager
(如果存在这样的事情:D,我猜)不要抛出,但阻止应用程序启动,如
NodeJSManager nodejsManager = new NodeJSManager();
boolean succeeded = nodejsManager.tryToStart();
if (!succeeded) {
// guard, it's useless to proceed
// cleanup and exit
}
我调用了这个方法tryToStart
,因为它可能发生服务器无法启动,你直接处理可执行文件和文件系统所以我会说这不再那么特别(但可能这是只是一个品味问题。)
重要的是,恕我直言,您将应用程序启动指定为一系列检查,例如节点和配置检查,而无需处理Exception
来处理代码流。
答案 1 :(得分:0)
我不喜欢经过检查的例外情况。我用来做(但不是一个很好的解决方案)是捕获已检查的Exception并以此方式将其作为运行时异常重新抛出:
catch (ExecuteException e) {
throw new RuntimeException (e);
}
已检查的异常“e”作为参数传递给RuntimeException。这样,我将一个checked转换为一个未经检查的异常。但正如我所说,这不是一个好的解决方案,它可能会导致更多的调试问题,它解决了。当“检查”异常时,往往是因为描述的错误是“严重的”。
答案 2 :(得分:0)
一种解决方案是创建自己的,更通用的异常类,它将扩展Exception
并将未处理的异常作为原因包装到您自己的异常中。这样,您至少可以减少方法签名中的一些异常。例如:
创建新类StartupException
或ConfigurationException
并在启动阶段将其作为原因捕获后将其抛出主异常。
此外,如果您要StartupException extends RuntimeException)
,则不必声明此类例外。
另一种方法是将所有内容都包装到RuntimeException
如果abowe不符合您的需求,那么这可能是设计缺陷,(如果您真的无法处理),您将不得不处理它。