我正在尝试创建一个管理多个Closeable
资源的Java类.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
上面的东西,它工作正常.但现在我有兴趣知道是否有更优雅的解决方案.
像这样使用try-with-resouces.
@Override public void close() throws IOException { try (Closeable cc = c; Closeable bb = b; Closeable aa = a;) { // do nothing } }