Dlaczego w Javie jest metoda finalize ().lang.Obiekt "chroniony"?

Z ciekawości,

Dlaczego modyfikator dostępu metody finalize() jest wykonany jako protected. Dlaczego nie może być public? Czy ktoś może mi wyjaśnić jakiś konkretny powód?

Również, dowiedziałem się, że finalize() metoda jest wywoływana tylko raz. Jeśli wywołam to dwa razy w moim programie wewnętrznie, co się dzieje? Czy Śmieciarz jeszcze raz to zadzwoni?

private void dummyCall() {
    try {
        finalize();
        finalize();
    } catch (Throwable e) {
        e.printStackTrace();//NOT REACHES EXCEPTION
    }
}
Author: bragboy, 2010-02-18

9 answers

Odpowiadam na twoje pytanie innym pytaniem:

Dlaczego finalize metoda nie powinna być chroniona?

Ogólnie rzecz biorąc, należy starać się zachować rzeczy tak prywatne, jak to tylko możliwe. Na tym polega enkapsulacja. W przeciwnym razie, można zrobić Wszystko public. finalize nie może być private (ponieważ klasy pochodne powinny mieć dostęp do niego, aby móc go nadpisać), więc powinno być przynajmniej protected, ale po co dawać większy dostęp, skoro nie jest pożądane?


Po uważniejszym przeczytaniu Twojego komentarza, chyba widzę teraz twój główny punkt. Myślę, że chodzi Ci o to, że skoro wszystko pochodzi od java.lang.Object i w konsekwencji uzyskuje dostęp do swoich protected członków, nie robiłoby to żadnej różnicy, aby to (lub jakakolwiek metoda w java.lang.Object w tym przypadku) była public w przeciwieństwie do protected. Osobiście uznałbym to za wadę projektową w Javie. Jest to rzeczywiście naprawione w C#. Problem nie polega na tym, dlaczego finalize jest chroniony. W porządku. Prawdziwym problemem jest to, że nie powinieneś być w stanie wywołać chronione metody w klasie bazowej poprzez odniesienie do obiektu typu klasy bazowej. Eric Lippert ma wpis na blogu omawiający, dlaczego zezwalanie na tego rodzaju dostęp do chronionych członków jest złym pomysłem, który jest {25]}bardziej rozwinięty na temat przepełnienia stosu w tym pytaniu {24]}.

 23
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:57

Dlaczego metoda finalize() ma dostęp modyfikator jest wykonany jako chroniony. Dlaczego nie może być publicznie?

Nie jest publiczny, ponieważ nie powinien być wywoływany przez nikogo innego niż JVM. Musi być jednak zabezpieczona, aby mogła zostać nadpisana przez podklasy, które muszą zdefiniować dla niej zachowanie.

Jeśli wywołam to dwa razy w moim programie, co się dzieje wewnętrznie?

Możesz nazywać to, co chcesz, w końcu to tylko metoda. Jednak, podobnie jak public static void main(String [] args), ma szczególne znaczenie dla JVM

Czy Śmieciarz nazwie to znowu?

TAK

 20
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 19:34:54
  • Finalize ma być wywoływane tylko przez gc i jako takie nie wymaga publicznego dostępu
  • Finalize ma gwarancję, że zostanie wywołane tylko raz przez gc , wywołanie go samemu złamie tę gwarancję, ponieważ gc nie będzie o tym wiedział.
  • każda klasa nadrzędna może upublicznić finalize, co moim zdaniem jest złe z powyższych powodów
  • finalize nie powinno zawierać dużo kodu, ponieważ każdy wyjątek rzucany przez finalize może zabić wątek finalizera gc.

Rant against finalize ()

  • Zarządzanie natywnymi zasobami lub dowolnym zasobem wymagającym wywołania dispose() lub close () może powodować trudne do znalezienia błędy, ponieważ zostaną one wydane tylko wtedy, gdy jvm skończy się pamięć, powinieneś zwolnić zasoby ręcznie. Finalize powinien być używany tylko do debugowania wycieków zasobów lub w przypadkach, w których ręczne zarządzanie zasobami to zbyt wiele pracy.
  • finalize zostanie wywołane w dodatkowym wątku gc i może powodować problemy z blokowaniem zasobów i tak dalej.
  • klasy referencyjne takie jak WeakReference i ReferenceQueue są alternatywnym (dość złożonym) sposobem radzenia sobie z czyszczeniem i mogą mieć takie same problemy jak finalize() dla zasobów natywnych.

Uważaj na błędy w powyższych wypowiedziach, jestem trochę zmęczony: -)

 12
Author: josefx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 20:04:26

Zobacz ten link , który go omawia.

W zasadzie, byłoby to najbardziej sensowne dla private, ponieważ powinno być wywoływane tylko przez JVM (garbage collector). Jednak aby podklasa mogła wywołać metodę rodzica finalize() jako część jej finalize(), musi to być protected.

(Edit - i tylko ogólna uwaga - użycie metody finalize() jest generalnie odradzane, ponieważ nie ma sposobu na zapewnienie, że zostanie ona kiedykolwiek wywołana. Chociaż to nie znaczy że nigdy nie będziesz miał okazji go użyć - to po prostu rzadkie.)

 3
Author: froadie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 19:23:58

Część o wywołaniu finalize() tylko raz dotyczy tylko wywołań z GC. Możesz sobie wyobrazić, że obiekt ma ukrytą flagę "finalize() został wywołany przez GC", a GC sprawdza tę flagę, aby wiedzieć, co zrobić z obiektem. Flaga nie jest w żaden sposób naruszona przez własne ręcznie wywołania do finalize().

Na temat finalizacji, przeczytaj Ten artykuł od Hansa Boehma (który jest dobrze znany ze swojej pracy na wywóz śmieci). Jest to otwieracz do finalizacji; w szczególności, Boehm wyjaśnia, dlaczego finalizacja jest koniecznie asynchroniczna. Konsekwencją jest to, że podczas gdy finalizacja jest potężnym narzędziem, bardzo rzadko jest odpowiednim narzędziem do danego zadania.

 3
Author: Thomas Pornin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 21:00:19

Nie jest to public (lub domyślny dostęp), ponieważ ma być wywoływany przez JVM wewnętrznie, gdy obiekt jest zbierany - to nie ma być wywoływane przez cokolwiek innego. I nie jest to private, ponieważ ma być nadpisane i nie można nadpisać prywatnych metod.

Jeśli wywołam to dwa razy w moim programie, co się dzieje wewnętrznie? Will the Śmieciarz nazwie to znowu?

Prawdopodobnie tak, ale trudno sobie wyobrazić scenariusz, w którym to miałoby jakikolwiek sens-punktem finalize() jest czyszczenie, gdy obiekt jest zbierany. I to nawet nie robi tak dobrze, więc jest to naprawdę coś, czego powinieneś całkowicie unikać, a nie eksperymentować.

 2
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 19:21:14

Finalize() jest używana tylko przez JVM do czyszczenia zasobów, gdy obiekt jest gromadzony. Rozsądne jest, aby Klasa określała, jakie działania powinny zostać podjęte w kolekcji, do których może potrzebować dostępu super.finalize (). Wywołanie finalize () przez zewnętrzny proces nie ma sensu, ponieważ zewnętrzny proces nie ma kontroli nad tym, kiedy obiekt jest zbierany.

 1
Author: Steve B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 19:21:35
/ Align = "center" bgcolor = "# e0ffe0 " / cesarz Chin / / align = center / () metoda jest wywoływana tylko raz. If I call to dwa razy w moim programie, wewnętrznie co się dzieje?

Prawdopodobnie zadajesz to pytanie pod wrażeniem destruktorów C++ ~. W Javie metoda finalize () nie robi żadnej magii (jak czyszczenie pamięci). Powinien ją nazywać Śmieciarz. Ale nie odwrotnie.

Polecam przeczytanie rozdziału w "efektywnej Javie" Joshuy Blocha. Mówi, że używanie finalizerów jest zła praktyka i może powodować wydajność i inne problemy, a jest tylko kilka przypadków, kiedy powinny być używane. Rozdział rozpoczyna się kolejnymi słowami:
Finalizery są nieprzewidywalne, często niebezpieczne i ogólnie niepotrzebne.
 1
Author: Roman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 19:35:41

Myślę, że powodem, dla którego finalize jest ochrona, może być to, że jest ona nadpisywana przez niektóre klasy w JDK, a te nadpisane metody są wywoływane przez JVM.

 1
Author: meerut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-06 21:18:07