Начиная с седьмой версии Java предлагает улучшенное управление ресурсами, которые должны быть закрыты после окончания работы с ними. К таким ресурсам относятся, например, файлы потоки, соединения с базами данных и сокетами. Этой цели служит специальная языковая конструкция try-with-resources. Для того чтобы это автоматическое закрытие работало создан специальный интерфейс
В Java 7 все классы ресурсов реализуют этот интерфейс. Его сигнатура выглядит следующим образом:
AutoCloseable
.

public interface AutoCloseable {
void close() throws Exception;
}
Интерфейс объявляет метод close()
, который автоматически вызывается для объектов, обслуживаемых конструкцией try-with-resources
.
Несмотря на то, что классы ресурсов в Java 7 реализуют этот интерфейс, множество библиотек, которыми вы пользуетесь этого не делают, поскольку библиотеку еще не обновили для работы с интерфейсом AutoCloseable или же вы просто не имеете возможности обновить библиотеку.
В большинстве случаев это решается просто. Наследуйте класс ресурса, который должен участвовать в конструкции try-with-resources
. Возьмем для примера ITextRenderer
(из проекта Flying Saucer). После окончания работы с ITextRenderer
, должен быть вызван метод finishPDF()
. Обычно вы бы делали это в блоке finally
. Но создавая новый класс, расширяющий ITextRenderer
и реализующий интерфейс AutoCloseable
, вы можете включить его в конструкцию try-with-resources
. Новый класс AutoCloseableITextRenderer
будет при этом выглядеть так:
public class AutoCloseableITextRenderer extends ITextRenderer implements AutoCloseable {
@Override
public void close() {
super.finishPDF();
}
}
Расширение оригинального класса в потомке, является наиболее разумным решением, поскольку новый класс по прежнему будет ITextRenderer
. В случае, если исходный класс объявлен как final
, необходимо использовать композицию. И вот как при этом будет выглядеть использование:
try (final AutoCloseableITextRenderer iTextRenderer = new AutoCloseableITextRenderer()) {
ByteArrayOutputStream out; // contains the data to be converted to PDF, not shown here.
iTextRenderer.setDocumentFromString(new String(out.toByteArray()));
iTextRenderer.layout();
iTextRenderer.createPDF(pdfOutputStream);
pdfOutputStream.flush();
}
Вот и все.
Пожалуйста, обратите внимание, что я не выбрасывал исключение из метода close()
в классе AutoCloseableITextRenderer
. В Javadoc интерфейса AutoCloseable
по этому поводу сказано следующее:
Хотя в метод интерфейса декларирован выбрасывать исключения Exception
, реализующим этот метод настоятельно рекомендуется использовать при реализации метода более специфические классы исключений, или вообще не выбрасывать исключений, если метод close()
не может упасть.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
youtu.be/2_ThvTc3X8Y?list=PLwcDaxeEINaemIX9OqrAjilBL6MTNikh8&t=2181