QUESTO DOVREBBE ESSERE OBSOLETO CON JAVA 9!
Usa java.util.Cleanerinvece! (O sun.misc.Cleanersul vecchio JRE)
Post originale:
Ho scoperto che l'uso di PhantomReferences ha quasi la stessa quantità di insidie dei metodi finalizer (ma meno problemi una volta che hai capito bene). Ho scritto una piccola soluzione (un framework molto piccolo per utilizzare PhantomReferences) per Java 8. Permette di utilizzare espressioni lambda come callback da eseguire dopo che l'oggetto è stato rimosso. È possibile registrare i callback per le risorse interne che dovrebbero essere chiuse. Con questo ho trovato una soluzione che funziona per me in quanto la rende molto più pratica.
https://github.com/claudemartin/java-cleanup
Ecco un piccolo esempio per mostrare come viene registrata una richiamata:
class Foo implements Cleanup {
public Foo() {
this.registerCleanup((value) -> {
try {
value.close();
} catch (Exception e) {
logger.warning("closing resource failed", e);
}
}, this.resource);
}
E poi c'è il metodo ancora più semplice per la chiusura automatica, che fa più o meno come sopra:
this.registerAutoClose(this.resource);
Per rispondere alle tue domande:
[allora a che serve?
Non puoi ripulire qualcosa che non esiste. Ma avrebbe potuto avere risorse che ancora esistono e devono essere ripulite in modo che possano essere rimosse.
Ma a cosa serve questo concetto / classe?
Non è necessariamente per fare qualcosa con alcun effetto diverso dal debug / registrazione. O forse per le statistiche. Lo vedo più come un servizio di notifica dal GC. Potresti anche utilizzarlo per rimuovere i dati aggregati che diventano irrilevanti una volta rimosso l'oggetto (ma probabilmente ci sono soluzioni migliori per questo). Gli esempi spesso menzionano la chiusura delle connessioni al database, ma non vedo come questa sia una buona idea dato che non potresti lavorare con le transazioni. Un framework applicativo fornirà una soluzione molto migliore per questo.
L'hai mai usato in uno dei tuoi progetti o hai qualche esempio in cui dovremmo usarlo? O questo concetto è fatto solo per il punto di vista dell'intervista;)
Lo uso principalmente solo per la registrazione. Quindi posso tracciare gli elementi rimossi e vedere come funziona GC e può essere ottimizzato. Non eseguirò alcun codice critico in questo modo. Se qualcosa deve essere chiuso, allora dovrebbe essere fatto in una dichiarazione di prova con le risorse. E lo uso nei test unitari, per assicurarmi di non avere perdite di memoria. Nello stesso modo in cui lo fa jontejj. Ma la mia soluzione è un po 'più generale.