3

我有一个关于异常处理和资源管理的问题,我想知道是否有人可以分享他们的意见。我需要执行一系列操作:读取应用程序设置、设置环境、执行这些操作,然后最终进行清理。清理涉及拆除环境,但这只有在首先成功设置时才会发生。

这是我的第一个(也是蹩脚的)方法:

try {
 readSettings();
 setupEnvironment();
} catch (Exception ex) {
 logStackTrace(ex);
 displayError(ex);
 closeCommThreads();
 return;
}

try {
 // do stuff
} catch (Exception ex) {
 logStackTrace(ex);
 displayError(ex);
} finally {
 teardownEnvironment();
 closeCommThreads();
}

这似乎有点难看,所以我决定寻找更好的解决方案。我做了一些背景阅读,很多文章投票支持更大的try/catch块并使用(双关语?)finally进行清理。所以这是我的第二次尝试:

try {
 readSettings();
 setupEnvironment();
 // do stuff
} catch (Exception ex) {
 logStackTrace(ex);
 displayError(ex);
} finally {
 teardownEnvironment();
 closeCommThreads();
}

为了完成这项工作,我必须删除顺序耦合,teardownEnvironment()以便可以随时调用它——之前或之后setupEnvironment()(对于编辑:有什么更好的方法吗?)。这是正确的方法吗?在设置之前拆掉我确实觉得有点奇怪。

编辑:

只是为了让它更明确一点:我通过在内部包含一个额外的检查来删除顺序耦合teardownEnvironment- 类似于if (!isSetup()) return;.

4

3 回答 3

2

如果两种方式都完成了您打算做的事情,那么既不是也不是错。

在我看来,第二种方法(大的 try/catch/finally 块)更易于阅读,因为您没有在方法体某处的 catch 块中“隐藏”返回语句。

此外,我认为消除方法(拆卸、设置)之间的相互依赖关系通常是一种很好的做法(例如,您可以独立地对这些方法进行单元测试)。如果没有设置任何内容,只需退出拆卸 - 无需对此感到奇怪:)

于 2010-11-26T11:44:40.410 回答
2

finally方法用于保证在引发异常之前,可以关闭/取消引用所使用的资源(并准备好进行垃圾收集)。这只是为了促进异常安全

您刚刚在这里讨论的内容称为Dispose Pattern。基本上,由于 Java GC 的自动特性,您正在为运行时环境进行资源清理。

您的第二种方法是正确的(这是一个 Dispose 模式),因为您正在有效地清理您的环境tearDownEnvironment(),在 JVM GC 启动之前关闭所有资源。

额外信息:资源获取是否初始化 可以启发你?

于 2010-11-26T11:45:49.800 回答
1

那么通常你teardownEnvironment()会检查

isEnvironmentSetCorrectly()if(environment != null)或任何类似的

在你开始拆除之前。

因此,您不必对此“感到有些奇怪”,因为如果操作正确,就不会发生。

于 2010-11-26T11:37:14.367 回答