2010-01-22 11 views
11

Ho un oggetto con un determinato stato. L'oggetto viene passato in giro e lo stato è temporaneamente alterato. Qualcosa di simile:Java, esecuzione di un metodo quando termina l'ambito dell'oggetto

public void doSomething(MyObject obj) { 
    obj.saveState(); 
    obj.changeState(...); 
    obj.use(); 
    obj.loadState(); 
} 

In C++ è possibile utilizzare il campo di applicazione di un oggetto per eseguire del codice quando si costruisce e distructing, come

NeatManager(MyObject obj) { obj.saveState(); } 
~NeatManager() { obj.loadState(); } 

e chiamarlo come

void doSomething(MyObject obj) { 
    NeatManager mng(obj); 
    obj.changeState(); 
    obj.use(); 
} 

Questo semplifica il lavoro, perché il salvataggio/carico è vincolato con l'ambito dell'oggetto NeatManager. È possibile fare qualcosa di simile in Java? C'è un modo per chiamare un metodo quando l'oggetto esce dall'ambito in cui è stato dichiarato? Non sto parlando di finalize() né di "distruzione" (garbage collection), mi interessa l'ambito.

Grazie

risposta

12

No, non esiste una cosa del genere. Il più vicino è probabilmente un try/finally block:

try 
{ 
    obj.changeState(...); 
    obj.use(); 
} 
finally 
{ 
    obj.loadState(); 
} 

Questo assicura che loadState() viene chiamato anche quando viene generata un'eccezione o c'è uno dei primi return.

5

No, non c'è niente del genere. Il più vicino che hai è provare/finalmente.

In C# c'è la dichiarazione using, che esegue un metodo Dispose alla fine:

using (Stream x = ...) 
{ 
} // x.Dispose() is called here, in a finally block 

C'è una possibilità che Java 7 guadagnerà qualcosa di un po 'come questo, ma non credo che nulla è stato impostato in pietra ancora.

+0

Grazie, interessante sentire su questo in Java7. – AkiRoss

-1

Risposta breve: No.

risposta Medi: La pratica migliore in questa situazione è quello di utilizzare un blocco try ... finally.

Risposta più lunga: C++ in realtà non ti dà neanche questo: i distruttori del C++ vengono eseguiti su de-allocazione. Se non si riesce a deallocare un oggetto e tutti i riferimenti ad esso non rientrano nell'ambito, il distruttore non verrà chiamato.

Per inciso, se la raccolta dei dati inutili in Java era il conteggio dei riferimenti, i finalizzatori implementavano esattamente questo comportamento.

+8

Infatti, il C++ supporta esattamente ciò che l'OP stava chiedendo. –

+1

Non capisco perché lo dici nella lunga risposta.Ho pensato che tutti gli oggetti che sono stati distrutti dopo che la funzione è stata eseguita, poiché lo stack è stato liberato da tutti gli oggetti allocati. Inoltre, sono abbastanza sicuro che questa è una buona pratica, come ho letto su GOTW, ma non sono sicuro e controllerò. Modifica: non sono sicuro se fosse GotW, Eccezionale C++ o Eccezionale C++: \ – AkiRoss

+0

Vero, i distruttori C++ verranno richiamati sugli oggetti allocati nello stack quando lo stack che li fa riferimento viene deallocato. Tuttavia, sugli oggetti allocati nell'heap (ovvero la maggior parte degli oggetti sulla maggior parte dei programmi), il distruttore verrà chiamato solo su una distruzione esplicita usando la parola chiave 'delete'. – jwoolard

2

Come nota aggiuntiva, non si è tentati di utilizzare il metodo Object.finalize(), che viene eseguito quando un oggetto è GC, poiché non si ha alcun controllo su quando l'oggetto viene raccolto.

+0

Sì, grazie. Ho letto un po 'di finalize() ma ho visto che non è il caso. Grazie. – AkiRoss

Problemi correlati