Починаючи з сьомої версії Java пропонує покращене керування ресурсами, які мають бути закриті після закінчення роботи з ними. До таких ресурсів відносяться, наприклад, потоки файли, з'єднання з базами даних і сокетами. Цій меті є спеціальна мовна конструкція try-with-resources. Для того щоб це автоматичне закриття працювало створено спеціальний інтерфейс
AutoCloseable
. У Java 7 всі класи ресурсів реалізують цей інтерфейс. Його сигнатура виглядає так:
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()
не може впасти.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ