W JAVA 9 TO POWINNO BYĆ PRZESTARZAŁE!
Użyj java.util.Cleaner
zamiast tego! (Lub sun.misc.Cleaner
w starszym JRE)
Oryginalny post:
Odkryłem, że użycie PhantomReferences ma prawie taką samą liczbę pułapek jak metody finalizujące (ale mniej problemów, gdy dobrze to zrobisz). Napisałem małe rozwiązanie (bardzo mały framework do używania PhantomReferences) dla Javy 8. Pozwala na użycie wyrażeń lambda jako wywołań zwrotnych uruchamianych po usunięciu obiektu. Możesz zarejestrować wywołania zwrotne zasobów wewnętrznych, które powinny zostać zamknięte. Dzięki temu znalazłem rozwiązanie, które działa dla mnie, ponieważ jest znacznie bardziej praktyczne.
https://github.com/claudemartin/java-cleanup
Oto mały przykład pokazujący, jak rejestrowane jest wywołanie zwrotne:
class Foo implements Cleanup {
public Foo() {
this.registerCleanup((value) -> {
try {
value.close();
} catch (Exception e) {
logger.warning("closing resource failed", e);
}
}, this.resource);
}
Jest jeszcze prostsza metoda automatycznego zamykania, działająca mniej więcej tak samo, jak powyżej:
this.registerAutoClose(this.resource);
Aby odpowiedzieć na Twoje pytania:
[w takim razie jaki z tego pożytek]
Nie możesz posprzątać czegoś, co nie istnieje. Ale mógł mieć zasoby, które nadal istnieją i wymagają oczyszczenia, aby można je było usunąć.
Ale jaki jest pożytek z tego pojęcia / klasy?
Niekoniecznie jest to robić coś innego niż debugowanie / rejestrowanie. A może dla statystyk. Widzę to bardziej jak usługę powiadomień z GC. Możesz również chcieć użyć go do usunięcia zagregowanych danych, które stają się nieistotne po usunięciu obiektu (ale prawdopodobnie są na to lepsze rozwiązania). Przykłady często wspominają o zamknięciu połączeń z bazą danych, ale nie widzę, jak to jest dobry pomysł, ponieważ nie można pracować z transakcjami. Framework aplikacji zapewni znacznie lepsze rozwiązanie tego problemu.
Czy kiedykolwiek użyłeś tego w którymś ze swoich projektów, czy masz jakiś przykład, gdzie powinniśmy to wykorzystać? A może jest to koncepcja stworzona tylko z punktu widzenia wywiadu;)
Używam go głównie do logowania. Mogę więc prześledzić usunięte elementy i zobaczyć, jak działa GC i można je dostosować. Nie uruchamiałbym w ten sposób żadnego krytycznego kodu. Jeśli coś wymaga zamknięcia, należy to zrobić w instrukcji try-with-resource. Używam go w testach jednostkowych, aby upewnić się, że nie mam żadnych wycieków pamięci. Tak samo jak robi to jontejj. Ale moje rozwiązanie jest nieco bardziej ogólne.