metoda finalizacji, zamykany interfejs, try-with-resources(java7) - 1

Witaj Amigo!

Postanowiłem ponownie omówić z tobą metodę finalize () .

Jeśli pamiętasz, finalize() to specjalna metoda, która jest wywoływana na obiekcie, zanim zostanie
on zniszczony przez moduł wyrzucania elementów bezużytecznych.

Głównym celem tej metody jest uwolnienie używanych zewnętrznych zasobów innych niż Java: zamykanie plików, strumieni we/wy itp.

Niestety metoda ta nie uzasadnia pokładanych w niej nadziei. Maszyna Java może opóźnić zniszczenie obiektu, jak również wywołanie metody finalize, tak długo, jak chce. Co więcej, wcale nie gwarantuje, że ta metoda zostanie wywołana. W wielu sytuacjach ze względu na „optymalizację” nie jest to tzw.

Podam dwa cytaty:

Joshua Bloch dobrze opisał tę metodę: link
Krótki fragment:

  1. finalize() może być użyte tylko w dwóch przypadkach:
    1. Sprawdzanie/czyszczenie zasobów za pomocą logowania.
    2. Podczas pracy z kodem natywnym, który nie jest krytyczny dla wycieku zasobów.
  2. finalize() spowalnia GC oczyszczający obiekt 430 razy
  3. finalize() nie może zostać wywołana
Jeśli powiem na rozmowie kwalifikacyjnej, że sfinalizowanie jest szkodliwą i niebezpieczną kulą, która myli się z jej istnieniem, to będę miał rację?

— Tak, uszczęśliwiłaś mnie, Ellie.

- Aby zastąpić metodę finalize w Javie 7, pojawiła się nowa konstrukcja. Nazywa się to try-with-resources . To nie jest dokładnie zamiennik finalizacji - raczej alternatywne podejście.

- Jak try-catch, tylko z zasobami?

- Prawie jak próba złapania . Faktem jest, że w przeciwieństwie do metody finalize (), blok ultimate z konstrukcji try-catch-finally jest zawsze wywoływany. Tego używali programiści, gdy trzeba było zagwarantować uwolnienie zasobów, zamknięcie strumieni itp.
Przykład:

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

Bez względu na to, czy blok try zadziałał normalnie , czy też został tam zgłoszony wyjątek, blok ostatecznie będzie zawsze wywołany i będzie można tam zwolnić zajęte zasoby.

Dlatego w Javie 7 postanowili uczynić to podejście oficjalnym i oto, co z tego wyszło:

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

Jest to specjalna konstrukcja try o nazwie try-with-resources (podobnie jak druga dla kolekcji for nazywa się foreach ).

Zauważ, że po try następują nawiasy, w których deklarowane są zmienne i tworzone są obiekty. Tych obiektów można używać wewnątrz bloku try, oznaczonego nawiasami {}. Kiedy wykonywanie poleceń blokowych try zakończy się, bez względu na to, czy zakończyło się normalnie, czy wystąpił wyjątek, metoda close() zostanie wywołana na obiekcie utworzonym w nawiasach ();

- Jakie interesujące. Ten zapis jest znacznie bardziej zwarty niż poprzedni. Chciałbym ją bardziej zrozumieć.

„To nie jest takie trudne, jak myślisz.

- Czy mogę w nawiasach wskazać obiekty moich zajęć?

„Tak, oczywiście, inaczej te wsporniki byłyby mało przydatne.

- A jeśli muszę wywołać inną metodę podczas wychodzenia z bloku try, gdzie mogę to określić?

Tutaj wszystko jest trochę cieńsze. Java 7 wprowadziła ten interfejs:

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

Możesz dziedziczyć swoją klasę z takiego interfejsu. Następnie jego obiekty mogą być używane wewnątrz try-with-resources. Tylko obiektów tego typu można używać w nawiasach try-with-resources do „automatycznego zamykania”.

- Tj. Będę musiał zastąpić metodę zamykania i napisać w niej kod, aby „wyczyścić” mój obiekt, ale czy nie mogę określić innej metody?

- Tak. Można jednak określić wiele obiektów, oddzielając je średnikiem:

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

Lepiej, ale nie tak fajnie, jak się spodziewałem.

Nie jest tak źle, przyzwyczaisz się. Z czasem.