Зачем нужен усовершенствованный и появившийся в JDK 7 оператор try-c-ресурсами?
try (спецификация_ресурса) {
//использование ресурса
{
Оператор try-c-ресурсами реализует принцип автоматического управления ресурсами, целью которого является избежать, например, утечек памяти, в случаях когда ресурс по каким-то причинам не освобождается, если он больше не нужен.
Неудачный исход закрытия файла может привести к "утечкам памяти", поскольку неиспользуемые ресурсы оперативной памяти останутся выделенными.(стр 365)
try ( FileInputStream res = new FileInputStream(args[O])) {
//использование ресурса
}
Оператор try-c-ресурсами позволяет объявить и проинициализировать ресурс (в круглых скобках после оператора try), создав переменной ресурса локальный контекст в блоке try. По завершении этого блока переменная удаляется, а значит и ресурс автоматически закрывается.
Отсюда отпадает необходимость явного закрытия ресурса методом close() в блоке оператора finally.
try-catch with resources был придумал лишь для того, чтобы избежать шаблонного кода.
Давайте попробуем написать, простой метод, для чтения первой строки из файла. До java 7 он выглядел бы следующим образом:
private static String readFirstLine(String fileName) {
BufferedReader reader = null;
String line = null;
try {
reader = new BufferedReader(new FileReader(fileName));
line = reader.readLine();
reader.close();
} catch (IOException e) {
try {
reader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return line;
}
Заметили, что в блоке catch нам нужен еще один блок для обработки исключений, т.к. мы должны закрыть ресурс, но операция закрытия в свою очередь тоже может выбросить исключение.
Не стоит так же забывать, что try-catch with resources позволяет не думать об освобождении ресурсов. Как только выполнение программы покидает область видимости ресурса/ресурсов, у них автоматические вызывается метод java.lang.AutoCloseable.close()
По сути, данную конструкцию можно представить, как метод, который принимает на вход какой то блок кода, требующий выполнения и список ресурсов, которые необходимо освободить после его выполнения.
private static void invoke(Callable<Void> task, Closeable... resources) throws Exception {
Exception exception = null;
try {
task.call();
} catch (Exception e) {
exception = e;
} finally {
for (Closeable closeable : resources)
try {
closeable.close();
} catch (Exception e) {
if (exception == null)
exception = e;
else
exception.addSuppressed(e);
}
}
if (exception != null)
throw exception;
}
Продвижение своими сайтами как стратегия роста и независимости