gpt4 book ai didi

java - 用 Java 编写类似展开的清理代码

转载 作者:行者123 更新时间:2023-12-02 00:07:26 27 4
gpt4 key购买 nike

假设我的类有一个获取资源的方法 start() 和释放资源的 stop() 方法。类的start方法可以调用成员对象的start()方法。如果其中一个成员对象的 start() 引发异常,我必须确保为 start() 成功的所有成员对象调用 stop() 。

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 没有 goto。请注意,不允许对尚未启动的对象调用 stop() - 我正在寻找与上述代码完全相同但更短的代码。

到目前为止,我想到的唯一解决方案是使用 boolean 值来记住启动的内容,如下所示:

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

我知道“finally”和“try-with-resources”,但是这些在这里似乎都不适用,因为如果没有异常(exception),资源不应该被释放。

附注这不是关于我使用异常或我的程序设计的问题。这专门针对初始化代码失败时的清理。

最佳答案

如何将您启动的内容添加到堆栈中,然后当您需要停止内容时,将所有内容从堆栈中弹出并停止它。

private Deque<Stoppable> toStop = new ArrayDeque<Stoppable>();

public void start() throws Exception {
try {
start(a);
start(b);
start(c);
start(d);
} catch (Exception e) {
stop();
throw e;
}
}

private void start(Stoppable s) throws Exception {
s.start();
toStop.push(s);
}

public void stop() {
while (toStop.size > 0) {
toStop().pop().stop();
}
}

这需要您开始通过接口(interface)或子类化来拥有某种常见的 stop() ,但我想它们很可能已经这样做了。

关于java - 用 Java 编写类似展开的清理代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14959516/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com