Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
В случае с Java деструкторов нет как таковыхСправедливости ради стоит отметить, что в Java есть финализаторы, которые вызываются когда объект собирается сборщиком мусора.
потребовать гарантий, что освобождение ресурсов не будет кидать исключений, мы можемМетод close() у некоторых объектов (например буфферизированный output stream) не только освобождает ресурсы, а и может производить запись (и это не зависит от языка программирования, в С++ ofstream::close() тоже сбрасывает буфер). Как Вы предлагаете проверять на ошибку в таком случае? Как в C++? Делать мануально close() в области видимости (т.е. до вызова деструктора) и проверять флаг failbit в iostate (или ловить исключение)? Разве это будет «лаконично»?
Но действительно, почему не сделать так, чтобы освобождение ресурсов гарантированно исполнялось?Потому, что это невозможно в общем случае.
InputStream g1 = new InputStream(...)
try{
//Some actions
OutputStream g2 = new OutputStream(...);
try {
//Some actions
InputStream g3 = new InputStream(...);
try{
//Some actions
} finally {
IOUtils.closeQuietly(g3);
}
//Some actions
g2.flush();
} finally {
IOUtils.closeQuietly(g2);
}
//Again, some actions
} finally {
IOUtils.closeQuietly(g1);
}
Closer closer = Closer.create();
try {
InputStream g1 = closer.register(new InputStream(...));
// some actions
OutputStream g2 = closer.register(new OutputStream(...));
// some actions
InputStream g3 = closer.register(new InputStream(...));
// some actions
} catch (Throwable e) {
throw closer.rethrow(e);
} finally {
closer.close();
}
Кроме того, пропадает информация об исключении из close(), если основной код выбрасывает исключение.
e.getTargetException() не годится?OutputStream os = null;
try {
os = ...
} finally {
...
}
} catсh(Throwable t) {
Closer.rethrow()import java.io.*;
class tmp {
public void myMethod() throws IOException {
try {
File f = File.createTempFile("",""); // это ради IOException
f.delete();
} catch (Throwable t) {
throw t;
}
}
}
public <T extends Throwable> T rethrow(T throwable) throws T {/*...*/}
throw closer.rethrow(e);, а не просто closer.rethrow(e);?public < T extends Throwable > T rethrow(Class< T > clazz, T throwable) throws T
Но собственно такой метод там есть.Throwable t? catch (MyException e) {
throw resource.rethrow(e);
}
И добавил MyException в список. Для ловли всех остальных я бы добавил метод rethrowUnknow c такой сигнатурой, какая у них сейчас.AggregateIOException extends IOException (самописное), которое бы эмулировало addSuppressed?
Правильно освобождаем ресурсы в Java