Słowo kluczowe “finalize” w Javie

Słowo kluczowe “finalize” w Javie

Cześć! 

     Wraz z dzisiejszym wpisem chciałbym zakończyć serię o słowach kluczowych w języku Java. Jeśli przegapiłeś poprzednie wpisy, zachęcam do nadrobienia zaległości:

Już poraz ostatni zacytuje słynne zdanie z poprzednich wpisów: słowa kluczowe to jedno z częstych pytań w kontekśćie rekrutacji na java junior developerów. Pytanie brzmi zazwyczaj: “wymień różnicę między „final”, „finally” oraz „finalize” wraz z przykładami praktycznymi”. 

W dzisiejszym wpisie na czynniki pierwsze rozłożymy słowo “finalize“, tym samym zamkniemy serię o słowach kluczowych – do dzieła!

Definicja

     Metoda finalize jest metodą chronioną, zdefiniowaną w klasie Object. Wywoływana jest przez “Garbage Collector” na obiektach, do których nie ma już odwołań / referencji. Powszechnie nazywana jest po prostu “finalizatorem“. Tak jak w przypdadku każdej innej niefinalnej metody, możemy nadpisać tą metodę. Głównym celem “finalize” jest zwolnienie zasobów wykorzystywanych przez obiekty, zanim zostaną one usunięte z pamięci. Finalize może działać jako główny mechanizm dla operacji czyszczenia lub jako zabezpieczenie, gdy inne metody zakończą się niepowodzeniem. 

Przykład

W celu lepszego zrozumienia działania “finalize“, przyjrzyjmy się praktycznemu przykładowi:

Finalize - przykład praktyczny [1]. www.biegajacyprogramista.pl

Klasa “Finalizator” posiada pole “czytacz“, które odwołuje się do zasobu “closeable“. Gdy tworzony jest obiekt z tej klasy, razem z nim tworzy się nowa instancja BufferedReader, która czyta z pliku w classpath.

Taka instancja używana jest w metodzie “czytajPierwszaLinie()” w celu przeczytania pierwszej linii w podanym pliku. Warto zauważyć, że w podanym kodzie nasz “czytacz” nie jest zamknięty. Można to zrobić za pomocą finalizatora:

Finalize - przykład praktyczny [2]. www.biegajacyprogramista.pl

Co udowodniono w powyższym przykładzie, nasz “finalize” jest zadeklarowany tak samo jak każda normalna metoda.

W praktycze czas, w którym “Garbage Collector” wywołuje wszystkie finalizatory, zależy od implementacji wirtualnej maszyny javy oraz warunków systemowych, na które zwyczajnei nie mamy wpływu.

W celu nauki i aby “Garbage Collector” zadziałał natychmiastowo, skorzystam również z metody System.gc(). W prawdziwych systemach nie powinniśmy wywoływać tej metody jawnie, ponieważ:

  • wirtualna maszyna javy lepiej wie, kiedy “Garbage Collector” musi zostać wywołany,
  • jest to kosztowne pod względem zasobów,
  • nie powoduje to natychmiastowego działania “Garbage Collector” a jedynie jest to wskazówka dla wirtualnej maszyny javy żeby zacząć działać/

Poniżej wcześniej zapowiadany kod, demonstrujący przypadek testowy z udziałem finalizatora:

Finalize - przykład praktyczny [3]. www.biegajacyprogramista.pl

W pierwszej linii tworzony jest obiekt “Finalizator“, a następnie wywoływana jest jego metoda “czytajPierwszaLinie“. Obiekt nie jest przypisany do żadnej zmiennej, więc jak najbardziej kwalifikuje się do “wyczyszczenia” po przywołaniu “Garbage Collectora“.

Asercja w teście weryfikuje zawartość pliku wejściowego i jest używana tylko po to, aby udowodnić, że nasza klasa działa zgodnie z oczekiwaniami. W momencie uruchomienia testu, na konsoli pojawi się komunikat o zamknięciu czytnika w finalizatorze. Oznacza to, że metoda “finalize” została wywołana.

Powody, dla których powinniśmy unikać finalizatorów

Jak większość, wszystko ma swoje wady.

  • wadą finalizatora jest szybkość jego działania a w zasadzie jego brak. Nigdy nie jesteśmy pewni, kiedy finalizator zostanie wykonany, ponieważ uruchomienie procesu “zbierania śmieci” może nastąpić w każdej chwili. Samo w sobie niest jest to problemem, ponieważ prędzej czy później finalizator zostanie wykonany. Jednakże zasoby systemowe niestety nie są ograniczone. Może się więc zdarzyć sytuacja, w której zabraknie zasobów zanim nastąpi czyszczenie, co może spowodować awarię naszej aplikacji.
  • finalize” ma również wpływ na “przenośność” programu. Dopóki “Garbage Collector” jest zależny od implementacji maszyny wirtualnej javy, to program może działać bardzo dobrze na jednym systemie, a na drugim zachowywać się już mniej wydajnie.
  • finalize” jest kosztowne pod względem wydajności. W szczególności, kiedy JVM musi wykonać o wiele więcej operacji podczas konstruowania i niszczenia obiektów zawierających niepusty finalizator.
  • finalize” nie obsługuje wyjątków. Jeśli finalizator rzuci wyjątek, proces finalizacji zostanie zatrzymany, pozostawiając obiekt w uszkodzonym stanie bez żadnego powiadomienia.

Podsumowanie

     Myślę, że wspólnie możemy stwierdzić, że “finalize” nie wydaje się tak trywialne jak “final” oraz “finally“. Finalizator ma wiele pułapek i należy to traktować jako zabezpieczenie na pewne wyjątkowe sytuacje, lecz zawsze musimy pamiętać, że nie ma pewności kiedy finalizator się wykona. Wydaje się, że wszystkie trzy słowa kluczowe w Javie zostały omówione w sposób szczegółowy i podczas rozmowy kwalifikacyjnej poza suchą definicją każdy z nas będzie umiał podać praktyczny przykład oraz wady czy zalety takiego rozwiązania.

Pozdrawiam serdecznie,
biegajacyprogramista.pl

Dodaj komentarz

8 + fifteen =

Close Menu