假设我的类有一个获取资源的方法start()和释放资源的stop()方法。类的start方法可以调用成员对象的start()方法。如果其中一个成员对象的start()引发异常,我必须确保start()成功的所有成员对象都调用stop()。在Java中编写类似展开的清理代码
class X {
public X()
{
a = new A();
b = new B();
c = new C();
d = new D();
}
public void start() throws Exception
{
try {
a.start();
} catch (Exception e) {
throw e;
}
try {
b.start();
} catch (Exception e) {
a.stop();
throw e;
}
try {
c.start();
} catch (Exception e) {
b.stop();
a.stop();
throw e;
}
try {
d.start();
} catch (Exception e) {
c.stop();
b.stop();
a.stop();
throw e;
}
}
public void stop()
{
d.stop();
c.stop();
b.stop();
a.stop();
}
private A a;
private B b;
private C c;
private D d;
}
注意清理代码的二次增长。什么是最好的方式(最少的代码)做清理?在C中,我可以轻松地使用函数底部的清除代码和“goto”跳转到适当的位置,但是Java没有转到。请注意,不允许在未启动()的对象上调用stop()ed - 我正在查找与上面的代码完全等效但代码更短的代码。
到目前为止,我已经来到了唯一的解决办法是使用布尔记住什么开始,像这样:
public void start() throws Exception
{
boolean aStarted = false;
boolean bStarted = false;
boolean cStarted = false;
boolean dStarted = false;
try {
a.start();
aStarted = true;
b.start();
bStarted = true;
c.start();
cStarted = true;
d.start();
dStarted = true;
} catch (Exception e) {
if (dStarted) d.stop();
if (cStarted) c.stop();
if (bStarted) b.stop();
if (aStarted) a.stop();
throw e;
}
}
我知道“终于”和“尝试 - 与资源”,但这两者似乎都不适用,因为如果没有例外,资源不应该被释放。
P.S.这不是关于我使用例外或我的程序设计的问题。这特别是关于在初始化代码失败的情况下清理。
当您在非启动资源上调用“stop”时会发生什么? – assylias 2013-02-19 14:11:07
我刚才提到过“不允许在未启动()ed的对象上调用stop()”。在start()和stop()函数中可能有assert()。 – 2013-02-19 14:12:34
使stop()方法更加健壮,并随时调用它。 – 2013-02-19 14:12:42