2010-01-22 4 views
11

Ich habe ein Objekt mit einem bestimmten Status. Das Objekt wird herumgereicht und sein Zustand wird vorübergehend verändert. Etwas wie:Java, Ausführen einer Methode, wenn der Objektbereich endet

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

In C++ ist es möglich, den Umfang eines Objekts zu verwenden, einige Code ausgeführt werden, wenn die Konstruktion und distructing, wie

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

und nennen Sie es wie

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

Diese vereinfacht die Arbeit, da das Speichern/Laden mit dem Bereich NeatManager Objekt gebunden ist. Ist es möglich, so etwas in Java zu tun? Gibt es eine Möglichkeit, eine Methode aufzurufen, wenn das Objekt den Gültigkeitsbereich verlässt, in dem es deklariert wurde? Ich spreche nicht über finalize() noch "Zerstörung" (Garbage Collection), ich interessiere mich für den Anwendungsbereich.

Danke

Antwort

12

Nein, es gibt keine solche Sache. Die nächste ist wahrscheinlich ein try/finally-Block:

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

Dies stellt sicher, dass loadState() selbst aufgerufen wird, wenn eine Ausnahme ausgelöst wird oder es gibt eine frühes return.

5

Nein, es gibt nichts Vergleichbares. Der nächste, den du hast, ist versuchen/endlich.

In C# gibt es die using Anweisung, die eine Dispose Methode am Ende führt:

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

eine Möglichkeit gibt es, dass Java 7 etwas ein bisschen wie dieses gewinnen, aber ich glaube nicht, alles ist eingestellt worden in Stein noch.

+0

Dank, interessant zu hören, dazu in Java7:

Für Java 6 Sie die damit verbundene Frage sehen möchten. – AkiRoss

-1

Kurze Antwort: Nein.

Medium Antwort: Die beste Vorgehensweise in dieser Situation ist ein try ... finally Block zu verwenden.

Längere Antwort: C++ gibt Ihnen das auch nicht wirklich: C++ Destruktoren werden bei Aufhebung der Zuweisung ausgeführt. Wenn Sie die Zuordnung eines Objekts nicht aufheben und alle Verweise darauf nicht in den Geltungsbereich fallen, wird der Destruktor nicht aufgerufen.

Wenn Garbage Collection in Java Referenzzählung ist, würden die Finalizer genau dieses Verhalten implementieren.

+8

In der Tat unterstützt C++ genau das, wonach der OP gefragt hat. –

+1

Ich verstehe nicht, warum du das in der langen Antwort sagst.Ich dachte, dass alle Objekte nach der Funktion zerstört wurden, da der Stapel von allen zugewiesenen Objekten befreit wurde. Auch ich bin mir ziemlich sicher, dass dies eine gute Praxis ist, wie ich darüber auf GOTW gelesen habe, aber ich bin mir nicht sicher, und ich werde überprüfen. Edit: nicht sicher, ob es war, Exceptional C++ oder mehr Ausnahme C++: \ – AkiRoss

+0

True, C++ - Destruktoren werden auf Stack zugewiesene Objekte aufgerufen, wenn der Stapel, der auf sie verweist, freigegeben wird. Bei Heap-allokierten Objekten (d. H. Der überwiegenden Mehrheit der Objekte in den meisten Programmen) wird der Destruktor jedoch nur bei expliziter Zerstörung unter Verwendung des Schlüsselworts "delete" aufgerufen. – jwoolard

2

Als zusätzliche Anmerkung, nicht in Versuchung geraten, die Object.finalize() -Methode zu verwenden, die ausgeführt wird, wenn ein Objekt GC'd ist, da Sie keine Kontrolle darüber haben, wann das Objekt gesammelt wird.

+0

Ja, danke. Ich habe ein wenig über finalize gelesen(), aber ich habe gesehen, dass das nicht der Fall ist. Vielen Dank. – AkiRoss

Verwandte Themen