Я пытаюсь создать класс Java, который управляет несколькими ресурсами Closeable
. Решение С++ было бы простым и легко масштабируемым с большим количеством ресурсов:
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 при сохранении безопасности исключений? Он управляется тремя ресурсами, но все больше становится громоздким. (Если это была локальная область, я мог бы просто использовать инструкцию "try-with-resources", но это не применимо здесь.)
Я думал об этом, работая с java.rmi
. В конструкторе я создаю/просматриваю реестр, просматривая объекты и экспортируя объекты. Для закрытия() необходимо отменить регистрацию и исключить объекты. Я думал о создании объектов-оберток для обработки экспорта/экспорта (например, я бы сделал на С++, чтобы воспользоваться RAII), но потом я заметил, что это не поможет мне (я не настолько эксперт по Java, но я должен использовать его для университета).
В настоящий момент я использую что-то вроде ComposedResource2
выше, и он отлично работает. Но теперь мне интересно узнать, есть ли более элегантное решение.