Domanda

Esiste un modo per creare un gestore di registro che verrà chiamato esattamente nel momento in cui viene rilasciato l'ultimo riferimento a un determinato oggetto?

Un esempio potrebbe essere un oggetto che è supportato da un file di dati fisici e una volta che l'oggetto non è più referenziato, il file dovrebbe essere chiuso e rinominato. Sarebbe bello se ciò fosse possibile senza dover chiamare esplicitamente una "chiusura" metodo su quell'oggetto.

Tutti i meccanismi di notifica di cui sono a conoscenza nell'area di riferimento debole / fantasma affermano solo che la notifica avverrà in un determinato momento ma non vi è alcuna garanzia su quando ciò accadrà ...

È stato utile?

Soluzione

In breve, no.

La specifica Java ti nega esplicitamente la possibilità di sapere quando viene rilasciato l'ultimo riferimento. Le implementazioni (e le ottimizzazioni) di JVM dipendono da questo. Non c'è gancio.

Altri suggerimenti

Da quanto ho capito, e ho cercato per qualche tempo di trovare un "distruttore" per gli oggetti java, non c'è modo di sapere quando si perde l'ultimo riferimento. Java tiene traccia dei riferimenti agli oggetti ma, per motivi di prestazioni, aggiorna queste informazioni solo durante la garbage collection.

La cosa più vicina è il metodo finalize che dovrebbe essere chiamato durante la garbage collection ma non c'è alcuna garanzia che verrà chiamato anche allora.

Penso che WeakReference faccia quello che vuoi. Un riferimento debole viene inserito in ReferenceQueue non appena è debolmente raggiungibile (cioè tutti i riferimenti forti sono andati).

Vedi questo articolo di Ethan Nicholas .

Se sei preoccupato che alcuni riferimenti non raggiungano il ReferenceQueue allo spegnimento, tieni un elenco di tutti gli oggetti creati (usando WeakReferences o PhantomReferences). Aggiungi un hook di arresto che controlla l'elenco per eventuali riferimenti in sospeso ed esegui qualsiasi azione ti serva.

Il problema è, " Come si implementa questo, senza che qualcosa abbia un riferimento all'oggetto? "

Anche se potessi superare quel problema, supponiamo che con un servizio chiameremo HandleManager, quindi HandleManager dovrebbe creare un nuovo riferimento all'oggetto, per passare al gestore. Quindi, il gestore potrebbe (a) memorizzare un riferimento ad esso, il che confonderebbe il HandleManager che si aspettava di distruggere l'oggetto senza riferimento; oppure (b) rilasciare il riferimento, il che significa che il riferimento finale è stato nuovamente rilasciato, il che significa che l'handler deve essere richiamato di nuovo ....

Se hai bisogno di gestire risorse esterne come i file, il meglio che puoi fare in java è una funzione close () (qualunque sia il nome che scegli). Puoi utilizzare finalize () come cintura e bretelle " polizza assicurativa, ma che ha tempi imprevedibili. Quindi la tua linea di difesa principale deve essere la funzione close ().

Vedi la mia risposta Perché mai implementare finalize ()?

Questo non può essere fatto con Java: per quanto ne so, ha bisogno di un Garbage Collector che conta i riferimenti. Hai considerato l'apertura e la chiusura del file di dati fisici del tuo oggetto secondo necessità, piuttosto che tenerlo aperto per la vita dell'oggetto?

potresti sovrascrivere finalize () nel tuo oggetto, ma questo è problematico per ragioni che altri hanno menzionato.

Per il tuo esempio specifico, potresti dare un'occhiata all'utilizzo di qualcosa come File.deleteOnExit () , che rimuove il file all'uscita dalla VM.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top