2010-01-22 12 views
11

Tengo un objeto con un cierto estado. El objeto se pasa y su estado se altera temporalmente. Algo así como:Java, la ejecución de un método cuando el alcance del objeto finaliza

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

En C++ es posible utilizar el alcance de un objeto para ejecutar código cuando la construcción y distructing, como

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

y llamarlo como

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

Este simplifica el trabajo, porque el guardar/cargar está enlazado con el alcance del objeto NeatManager. ¿Es posible hacer algo como esto en Java? ¿Hay alguna manera de llamar a un método cuando el objeto sale del ámbito en el que se ha declarado? No estoy hablando de finalize() ni de "destrucción" (recolección de basura), estoy interesado en el alcance.

Gracias

Respuesta

12

No, no hay tal cosa. El más cercano es probablemente un try/finally:

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

Esto asegura que loadState() es llamada incluso cuando se produce una excepción o hay un temprano return.

5

No, no hay nada como eso. Lo más cercano que tienes es try/finally.

En C# está la declaración using, que ejecuta un método Dispose al final:

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

Hay una posibilidad de que Java 7 ganará algo un poco como esto, pero no creo que ha sido establecido nada en piedra todavía

+0

Gracias, interesante escuchar acerca de esto en Java7. – AkiRoss

-1

Respuesta corta: No.

respuesta Medio: La mejor práctica en esta situación es el uso de un bloque try ... finally.

Respuesta más larga: C++ realmente tampoco le da esto: los destructores C++ se ejecutan en la desasignación. Si no puede desasignar un objeto y todas las referencias al mismo quedan fuera del alcance, no se invocará el destructor.

Como un aparte, si la recolección de basura en Java era el conteo de referencias, los finalizadores implementarían exactamente este comportamiento.

+8

De hecho, C++ admite exactamente lo que el OP estaba preguntando. –

+1

No entiendo por qué dices eso en la respuesta larga.Pensé que todos los objetos se distruyeron después de que se realiza la función, ya que la pila se libera de todos los objetos asignados. Además, estoy bastante seguro de que esta es una buena práctica, ya que la leí en GOTW, pero no estoy seguro y la verificaré. Editar: no estoy seguro de si era GotW, Excepcional C++ o Más excepcional C++: \ – AkiRoss

+0

Cierto, se invocarán destructores C++ en objetos asignados a la pila cuando la pila que los referencia se desasigna. Sin embargo, en los objetos asignados en el montón (es decir, la gran mayoría de los objetos en la mayoría de los programas), el destructor solo será invocado en destrucción explícita utilizando la palabra clave 'delete'. – jwoolard

2

Como nota adicional, no se sienta tentado a utilizar el método Object.finalize(), que se ejecuta cuando un objeto es GC'd, ya que no tiene control sobre cuándo se recopila el objeto.

+0

Sí, gracias. Leí un poco acerca de finalizar() pero vi que no es el caso. Gracias. – AkiRoss

Cuestiones relacionadas