QUESTO DEVE ESSERE OBSOLETO CON JAVA 9!
Utilizzare invece java.util.Cleaner
! (O sun.misc.Cleaner
sui vecchi JRE)
Original post:
ho trovato che l'uso di PhantomReferences ha quasi la stessa quantità di insidie come metodi Finalizer (ma un minor numero di problemi una volta che si ottiene a destra). Ho scritto una piccola soluzione (un framework molto piccolo per usare PhantomReferences) per Java 8. Permette di usare espressioni lambda come callback da eseguire dopo che l'oggetto è stato rimosso. È possibile registrare i callback per le risorse interne che devono essere chiuse. Con questo ho trovato una soluzione che funziona per me in quanto rende molto più pratico.
https://github.com/claudemartin/java-cleanup
Ecco un piccolo esempio per mostrare come una richiamata è iscritto:
class Foo implements Cleanup {
//...
public Foo() {
//...
this.registerCleanup((value) -> {
try {
// 'value' is 'this.resource'
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, facendo più o meno come sopra:
this.registerAutoClose(this.resource);
per rispondere alle vostre domande:
[allora che cosa è l'uso di esso]
Non è possibile pulire qualcosa che non esiste. Ma avrebbe potuto avere risorse che esistono ancora e devono essere ripulite in modo che possano essere rimosse.
Ma a cosa serve questo concetto/classe?
Non è necessariamente necessario eseguire operazioni con effetti diversi dal debug/logging. O forse per le statistiche. Lo vedo più come un servizio di notifica dal GC. Si potrebbe anche volerlo usare per rimuovere dati aggregati che diventano irrilevanti una volta rimosso l'oggetto (ma probabilmente ci sono soluzioni migliori per questo). Gli esempi spesso menzionano le connessioni del database da chiudere, ma non vedo come questa sia una buona idea in quanto non si potrebbe lavorare con le transazioni. Un framework applicativo fornirà una soluzione molto migliore per questo.
Avete mai usato questo in uno dei vostri progetti, o avete qualche esempio in cui dovremmo usare questo? O è questo concetto fatto solo per il punto di vista dell'intervista;)
Lo uso principalmente per la registrazione. Quindi posso rintracciare gli elementi rimossi e vedere come funziona GC e può essere ottimizzato. Non vorrei eseguire alcun codice critico in questo modo. Se qualcosa deve essere chiuso, dovrebbe essere fatto in una dichiarazione try-with-resource. E lo uso nelle unit test, per assicurarmi che non ci siano perdite di memoria. Allo stesso modo di jontejj. Ma la mia soluzione è un po 'più generale.
Anche https://stackoverflow.com/a/9827686/632951 – Pacerier
Come non è possibile ottenere l'oggetto di riferimento di un PhantomReference, è un termine improprio completo: avrebbe dovuto essere chiamato 'FakeReference' o' NonReference'. – Pacerier
Ecco un altro thread con codice: https://stackoverflow.com/q/43311825/632951 – Pacerier