Począwszy od wersji 7, Java oferuje ulepszone zarządzanie zasobami, które powinny zostać zamknięte po zakończeniu pracy z nimi. Zasobami takimi są na przykład pliki, strumienie, połączenia z bazami danych i gniazda. Służy temu specjalna konstrukcja językowa try-with-resources. Aby to automatyczne zamykanie zadziałało, stworzono specjalny interfejs
AutoCloseable
. W Javie 7 wszystkie klasy zasobów implementują ten interfejs. Jego podpis wygląda następująco:
public interface AutoCloseable {
void close() throws Exception;
}
Interfejs deklaruje metodę close()
, która jest automatycznie wywoływana na obiektach obsługiwanych przez konstrukcję try-with-resources
. Chociaż klasy zasobów w Javie 7 implementują ten interfejs, wiele używanych przez Ciebie bibliotek tego nie robi, ponieważ biblioteka nie została jeszcze zaktualizowana do pracy z interfejsem AutoCloseable lub po prostu nie masz możliwości aktualizacji biblioteki. W większości przypadków można to łatwo rozwiązać. Dziedzicz klasę zasobów, która powinna uczestniczyć w try-with-resources
. Weźmy na przykład ITextRenderer
(z projektu Flying Saucer). Po zakończeniu pracy z ITextRenderer
metodą należy wywołać metodę finishPDF()
. Zwykle zrobiłbyś to w bloku finally
. Kiedy jednak utworzysz nową klasę, która rozszerza ITextRenderer
i implementuje interfejs AutoCloseable
, możesz umieścić ją w pliku try-with-resources
. Nowa klasa AutoCloseableITextRenderer
będzie wyglądać następująco:
public class AutoCloseableITextRenderer extends ITextRenderer implements AutoCloseable {
@Override
public void close() {
super.finishPDF();
}
}
Rozszerzenie oryginalnej klasy na potomka jest najrozsądniejszym rozwiązaniem, ponieważ nowa klasa nadal będzie ITextRenderer
. W przypadku, gdy oryginalna klasa jest zadeklarowana jako final
, należy użyć kompozycji. A tak wyglądałoby użycie:
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();
}
To wszystko. Pamiętaj, że nie zgłosiłem wyjątku od metody close()
w pliku AutoCloseableITextRenderer
. Dokument Javadoc interfejsu AutoCloseable
mówi na ten temat co następuje: Chociaż metoda interfejsu została zadeklarowana do zgłaszania wyjątków Exception
, zdecydowanie zaleca się osobom wdrażającym tę metodę, aby podczas implementowania metody korzystały z bardziej szczegółowych klas wyjątków lub w ogóle nie zgłaszały wyjątków, jeśli metoda close()
nie może ponieść porażkę.
GO TO FULL VERSION