try-with-resources-java

Начнем с предыстории. Для начала рассмотрим метод finalize() класса Object. Раз данный метод принадлежит классу Object, значит его наследуют все классы и соответственно объекты на базе этих классов. Метод finalize() — это специальный метод, который вызывается у объекта Java-машиной перед тем, как сборщик мусора уничтожит данный объект. Данный метод был придуман для освобождения внешних ресурсов, которые занимал данный объект. Под внешними ресурсами имеются ввиду файлы, потоки ввода-вывода и т. д.

Но есть один большой минус данного метода — Java-машина может отложить уничтожение объекта, как и вызов метода finalize() на сколько угодно. Более того, Java-машина вообще не гарантирует, что данный метод будет вызван. В куче ситуаций ради «оптимизации» метод finalize() не вызывается.

Начиная с 7 версии, в Java появился альтернативный подход к решению данной задачи. Называется данный подход — try-with-resources.

В отличие от метода finalize(), блок finally из конструкции try-catch-finally вызывается всегда. Этим и пользовались программисты, когда нужно было гарантированно освободить ресурсы, закрыть потоки и т.д.

InputStream is = null;
try
{
 is = new FileInputStream("c:/file.txt");
 is.read(…)
}
finally
{
 if (is!=null)
 is.close();
}

Независимо от того, нормально ли отработал блок try, или там возникло исключение, блок finally вызовется всегда, и там можно будет освободить занятые ресурсы.

Поэтому в Java 7 этот подход решили сделать официальным, и вот что из этого вышло:

try(InputStream is = new FileInputStream("c:/file.txt"))
{
 is.read(…)
}

Это специальная конструкция try, называемая try-with-resources. После try следуют круглые скобки, где объявляются переменные и создаются объекты. Эти объекты можно использовать внутри блока try, обозначенного скобками {}. Когда выполнение команд блока try закончится, независимо от того – нормально оно закончилось или было исключение, для объекта, созданного внутри круглых скобок (), будет вызван метод close(). Но для того чтобы иметь возможность создать объект внутри круглых скобок блока try необходимо имплементировать свой объект от специального интерфейса AutoCloseable.

public interface AutoCloseable
{
 void close() throws Exception;
}

Данный интерфейс имеет всего лишь один метод close(), который необходимо переопределить, и именно данный метод будет вызываться. Только объекты такого типа можно использовать внутри круглых скобок try-with-resources для «автоматического закрытия».

При необходимости внутри круглых скобок можно создавать несколько объектов, разделив их точкой с запятой. После последнего объекта точка с запятой не указывается.

try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
 is.read(…)
 os.write(…);
}