我正在尝试创建一个管理多个的Java类 Closeable
资源。 C ++解决方案可以直接使用大量资源轻松扩展:
class composed_resource
{
resource_a a;
resource_b b;
resource_c c;
composed_resource(int x)
: a(x), b(x), c(x)
{ }
~composed_resource()
{ }
};
我天真的Java解决方案:
public class ComposedResource implements Closeable
{
private final ResourceA a;
private final ResourceB b;
private final ResourceC c;
public ComposedResource(int x) /* throws ... */ {
a = new ResourceA(x);
try {
b = new ResourceB(x);
try {
c = new ResourceC(x);
} catch (Throwable t) {
b.close();
throw t;
}
} catch (Throwable t) {
a.close();
throw t;
}
}
@Override
public void close() throws IOException {
try {
a.close();
} finally {
try {
b.close();
} finally {
c.close();
}
}
}
}
略有改进的版本:
public class ComposedResource2 implements Closeable
{
private final ResourceA a;
private final ResourceB b;
private final ResourceC c;
public ComposedResource2(int x) /* throws ... */ {
try {
a = new ResourceA(x);
b = new ResourceB(x);
c = new ResourceC(x);
} catch (Throwable t) {
close();
throw t;
}
}
@Override
public void close() throws IOException {
try {
if (a != null) a.close();
} finally {
try {
if (b != null) b.close();
} finally {
if (c != null) c.close();
}
}
}
}
是否有更优雅的解决方案,避免嵌套的try-catch-blocks,同时仍保持异常安全?它可以通过三种资源进行管理,但更多的东西变得笨拙。 (如果它是本地范围,我可以使用“try-with-resources”语句,但这不适用于此。)
我在工作时想到了这一点 java.rmi
。在构造函数中,我正在创建/查找注册表,查找对象和导出对象。 close()需要取消注册和取消导出对象。我想创建包装器对象来处理导出/取消导出(就像我在C ++中用来利用RAII),但后来我注意到这对我没什么帮助(我不是那么多Java专家,但我必须用它来上大学)。
目前我正在使用类似的东西 ComposedResource2
以上,它工作正常。但现在我有兴趣知道是否有更优雅的解决方案。