¿Hay un destructor para Java?


594

¿Hay un destructor para Java? Parece que no puedo encontrar ninguna documentación sobre esto. Si no lo hay, ¿cómo puedo lograr el mismo efecto?

Para hacer mi pregunta más específica, estoy escribiendo una aplicación que trata con datos y la especificación dice que debería haber un botón 'restablecer' que devuelva la aplicación a su estado original recién lanzado. Sin embargo, todos los datos tienen que estar 'en vivo' a menos que la aplicación se cierre o se presione el botón de reinicio.

Siendo generalmente un programador de C / C ++, pensé que esto sería trivial de implementar. (Y, por lo tanto, planeé implementarlo en último lugar). Estructuré mi programa de manera que todos los objetos 'reiniciables' estarían en la misma clase para que pueda destruir todos los objetos 'vivos' cuando se presiona un botón de reinicio.

Estaba pensando si todo lo que hice fue simplemente desreferenciar los datos y esperar a que el recolector de basura los recolecte, ¿no habría una pérdida de memoria si mi usuario ingresara datos repetidamente y presiona el botón de reinicio? También estaba pensando que, dado que Java es bastante maduro como lenguaje, debería haber una manera de evitar que esto suceda o abordarlo con gracia.


77
Solo hay una pérdida de memoria si tiene referencias a objetos que no necesita. es decir, hay un error en su programa. El GC funcionará según lo necesite (a veces antes)
Peter Lawrey

17
La máquina virtual no ejecutará GC lo suficientemente pronto si está procesando datos rápidamente a través de objetos. La idea de que el GC siempre puede mantener el ritmo o tomar las decisiones correctas es una falacia.
Kieveli

1
@Kieveli ¿JVM no ejecutaría GC antes de dar un error?
WVrock

44
Sí, sería bueno si hubiera un destructor para Java que lo destruiría de una vez por todas.
Tomáš Zato - Restablece a Monica

Respuestas:


526

Debido a que Java es un lenguaje recolectado de basura, no puede predecir cuándo (o incluso si) se destruirá un objeto. Por lo tanto, no hay un equivalente directo de un destructor.

Hay un método heredado llamado finalize, pero esto se llama completamente a discreción del recolector de basura. Entonces, para las clases que necesitan un orden explícito, la convención es definir un método de cierre y usar finalizar solo para la verificación de la cordura (es decir, si no se ha llamado a cerrar, hágalo ahora y registre un error).

Hubo una pregunta que generó una discusión en profundidad de finalizar recientemente, por lo que debería proporcionar más profundidad si es necesario ...


55
¿"Close ()" en este contexto se refiere al método en java.lang.Autocloseable?
Sridhar Sarnobat

21
No, AutoCloseable se introdujo en Java 7, pero la convención 'close ()' ha existido por mucho más tiempo.
Jon Onstott

por qué no puedes predecir cuándo (o incluso si) un objeto será destruido. ¿Qué otra forma aproximada de predecir eso?
dctremblay

La destrucción de objetos @dctremblay la realiza el recolector de basura y el recolector de basura nunca puede ejecutarse durante la vida útil de la aplicación.
Piro dice reinstalar a Mónica el

44
Tenga en cuenta que el finalizemétodo ha quedado en desuso en Java 9.
Lii

124

Eche un vistazo a la declaración de prueba con recursos . Por ejemplo:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
} catch (Exception e) {
  ...
} finally {
  ...
}

Aquí el recurso que ya no se necesita se libera en el BufferedReader.close()método. Puede crear su propia clase que implemente AutoCloseabley usarla de manera similar.

Esta declaración es más limitada que finalizeen términos de estructuración del código, pero al mismo tiempo hace que el código sea más simple de entender y mantener. Además, no hay garantía de que finalizese llame a un método durante el tiempo de vida de la aplicación.


12
Me sorprende que esto tenga tan pocos votos. Es la respuesta real.
nurettin

20
No estoy de acuerdo con que sea la respuesta real. Si una instancia tiene un recurso que maneja durante un período de tiempo más largo, a través de múltiples llamadas a métodos, entonces probar con recursos no ayudará. A menos que esté bien cerrar y volver a abrir dicho recurso a la velocidad en que se llama a dichos métodos, no es un hecho general.
Eric

14
De hecho, esta no es la respuesta real. Es imposible usar esta estructura para gestionar la destrucción de un objeto a menos que la construcción y el uso del objeto estén completamente encapsulados por tryy finallyse use para forzar una llamada obj.finalize(). E incluso esta configuración no resuelve el problema que plantea OP: destrucción de objetos a mitad del programa desencadenada por un botón de "reinicio".
7yl4r

1
Otros usuarios han demostrado que esto se hace en el punto de entrada de su aplicación. Defina su variable globalmente. Inicialícelo en la función de entrada, con try. Desinicialice finalmente (cuando se cierra su aplicación). Es completamente posible.
TamusJRoyce

1
@nurettin Java 7 solo había estado fuera durante 3 meses cuando se hizo la pregunta, si eso ayuda a darle más sentido.
corsiKa 01 de

110

No, no hay destructores aquí. La razón es que todos los objetos de Java se asignan en montón y se recolecta basura. Sin la desasignación explícita (es decir, el operador de eliminación de C ++) no hay una forma sensata de implementar destructores reales.

Java admite finalizadores, pero están destinados a usarse solo como protección para los objetos que contienen un identificador de recursos nativos como sockets, identificadores de archivos, identificadores de ventanas, etc. Cuando el recolector de basura recolecta un objeto sin un finalizador, simplemente marca la memoria región como libre y eso es todo. Cuando el objeto tiene un finalizador, primero se copia en una ubicación temporal (recuerde, aquí estamos recolectando basura), luego se coloca en una cola de espera para ser finalizado y luego un hilo Finalizador sondea la cola con muy baja prioridad y ejecuta el finalizador.

Cuando se cierra la aplicación, la JVM se detiene sin esperar a que se finalicen los objetos pendientes, por lo que prácticamente no hay garantías de que sus finalizadores se ejecuten.


44
Gracias por mencionar los recursos nativos: esta es un área donde es útil un método "similar a un destructor".
Nathan Osman

Sí, ahora estoy enfrentando el mismo problema con la liberación de recursos / identificadores asignados a través de llamadas nativas a C ++.
nikk

@ddimitrov, en teoría, ¿podría Java implementar una desasignación explícita? ¿O es esto una contradicción lógica?
mils

1
@mils implementando ingenuamente la desasignación explícita rompería la suposición de Java de que cualquier referencia apunta a un objeto vivo. Puede iterar sobre todos los punteros y anular los alias, pero eso es más costoso que GC. O puede intentar utilizar algún sistema de tipo lineal (consulte "propiedad" en Rust), pero ese es un cambio importante de idioma. También hay otras opciones (consulte Memoria de ámbito JavaRT, etc.), pero en general la desasignación explícita no se ajusta bien al lenguaje Java.
ddimitrov

31

Se debe evitar el uso de los métodos finalize () . No son un mecanismo confiable para la limpieza de recursos y es posible causar problemas en el recolector de basura al abusar de ellos.

Si necesita una llamada de desasignación en su objeto, por ejemplo, para liberar recursos, use una llamada de método explícito. Esta convención se puede ver en las API existentes (por ejemplo, que se puede cerrar , Graphics.dispose () , Widget.dispose () ) y generalmente se llama a través de try / finalmente.

Resource r = new Resource();
try {
    //work
} finally {
    r.dispose();
}

Los intentos de usar un objeto desechado deberían generar una excepción de tiempo de ejecución (consulte IllegalStateException ).


EDITAR:

Estaba pensando, si todo lo que hice fue simplemente desreferenciar los datos y esperar a que el recolector de basura los recolecte, ¿no habría una pérdida de memoria si mi usuario ingresara datos repetidamente y presiona el botón de reinicio?

En general, todo lo que necesita hacer es desreferenciar los objetos; al menos, esta es la forma en que se supone que funciona. Si le preocupa la recolección de basura, consulte Java SE 6 HotSpot [tm] Ajuste de recolección de basura de máquina virtual (o el documento equivalente para su versión JVM).


1
Eso no es lo que significa la desreferencia. No es "establecer la última referencia de un objeto como nulo", sino obtener (leer) el valor de una referencia para que pueda usarlo en operaciones posteriores.

1
¿Try… finalmente sigue siendo un enfoque válido y recomendado? Supongamos que anteriormente estaba llamando a un método nativo en finalize (), ¿puedo mover la llamada a la cláusula finalmente? class Resource { finalize() { destroy(); } protected native void destroy(); } class Alt_Resource { try (Resource r = new Resource()) { // use r } finalize { r.destroy(); }
aashima

r no estaría al alcance del bloque finalmente. Por lo tanto, no puedes llamar a destruir en ese punto. Ahora, si corrige el ámbito para tener la creación del objeto antes del bloque de prueba, terminaría con el feo caso "antes de probar con recursos".
userAsh

21

Con Java 1.7 lanzado, ahora tiene la opción adicional de usar el try-with-resourcesbloque. Por ejemplo,

public class Closeable implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("closing..."); 
    }
    public static void main(String[] args) {
        try (Closeable c = new Closeable()) {
            System.out.println("trying..."); 
            throw new Exception("throwing..."); 
        }
        catch (Exception e) {
            System.out.println("catching..."); 
        }
        finally {
            System.out.println("finalizing..."); 
        } 
    }
}

Si ejecuta esta clase, c.close()se ejecutará cuando tryse deje el bloque y antes de que se ejecuten los bloques catchy finally. A diferencia del caso del finalize()método, close()se garantiza su ejecución. Sin embargo, no hay necesidad de ejecutarlo explícitamente en la finallycláusula.


¿Qué pasa si no usamos el bloque try-with-resources? Creo que podemos llamar a close en finalize () solo para asegurarnos de que se ha llamado a close.
shintoZ

3
@shintoZ como leí en las respuestas anteriores, no hay garantía de finalize()ejecución
Asif Mushtaq

14

Estoy totalmente de acuerdo con otras respuestas, diciendo que no confíe en la ejecución de finalizar.

Además de los bloques try-catch-finally, puede usar Runtime # addShutdownHook (introducido en Java 1.3) para realizar las limpiezas finales en su programa.

Eso no es lo mismo que los destructores , pero uno puede implementar un gancho de cierre con objetos de escucha registrados en los que se pueden invocar métodos de limpieza (cerrar conexiones de bases de datos persistentes, eliminar bloqueos de archivos, etc.), cosas que normalmente se harían en destructores . Nuevamente, esto no reemplaza a los destructores, pero en algunos casos, puede acercarse a la funcionalidad deseada con esto.

La ventaja de esto es tener un comportamiento de deconstrucción ligeramente acoplado del resto de su programa.


addShutdownHook aparentemente se introdujo en Java 1.3. De todos modos, está disponible para mí en 1.5. :) Vea esto: stackoverflow.com/questions/727151/…
skiphoppy

1
Para su información, en mi experiencia, no se llamarán los ganchos de cierre si usa el botón rojo "terminar" en Eclipse: toda la JVM se destruye inmediatamente, no se llaman con gracia los ganchos de cierre. Lo que significa que puede ver un comportamiento diferente durante el desarrollo y la producción si desarrolla usando eclipse
Hamy

11

No, java.lang.Object#finalizees lo más cerca que puedes estar.

Sin embargo, cuando (y si) se llama, no está garantizado.
Ver:java.lang.Runtime#runFinalizersOnExit(boolean)


55
Un método que puede o no ser llamado es esencialmente inútil en mi libro. Hubiera sido mejor no contaminar el idioma con un método especial inútil que en el mejor de los casos da una falsa sensación de seguridad. Nunca entenderé por qué los desarrolladores del lenguaje Java pensaron que finalizar era una buena idea.
antred

@antred Los desarrolladores del lenguaje Java están de acuerdo . Supongo que, en aquel entonces, para algunos de ellos, era la primera vez que diseñaban un lenguaje de programación y un entorno de tiempo de ejecución con recolección de basura. Lo que es menos comprensible, es por qué ese otro lenguaje administrado copió ese concepto a la vez, cuando ya se entendía que este concepto es una mala idea.
Holger

7

Primero, tenga en cuenta que dado que Java se recolecta basura, es raro que necesite hacer algo para destruir objetos. En primer lugar, porque normalmente no tiene ningún recurso administrado para liberar, y en segundo lugar, porque no puede predecir cuándo o si sucederá, por lo que no es apropiado para las cosas que necesita que ocurran "tan pronto como ya nadie use mi objeto. ".

Puede recibir una notificación después de que un objeto ha sido destruido usando java.lang.ref.PhantomReference (en realidad, decir que ha sido destruido puede ser ligeramente inexacto, pero si una referencia fantasma está en cola, entonces ya no es recuperable, lo que generalmente equivale a la misma cosa). Un uso común es:

  • Separe los recursos en su clase que necesitan ser destruidos en otro objeto auxiliar (tenga en cuenta que si todo lo que está haciendo es cerrar una conexión, lo cual es un caso común, no necesita escribir una nueva clase: la conexión a cerrar sería el "objeto auxiliar" en ese caso).
  • Cuando cree su objeto principal, cree también una PhantomReference a él. Haga que esto se refiera al nuevo objeto auxiliar, o configure un mapa desde los objetos PhantomReference a sus correspondientes objetos auxiliares.
  • Después de que se recolecta el objeto principal, la PhantomReference se pone en cola (o más bien se puede poner en cola, al igual que los finalizadores, no hay garantía de que lo sea alguna vez, por ejemplo, si la VM sale, entonces no esperará). Asegúrese de que está procesando su cola (ya sea en un hilo especial o de vez en cuando). Debido a la referencia dura al objeto auxiliar, el objeto auxiliar aún no se ha recopilado. Por lo tanto, haga la limpieza que desee en el objeto auxiliar, luego deseche la PhantomReference y, finalmente, también se recopilará el auxiliar.

También hay finalize (), que parece un destructor pero no se comporta como tal. Por lo general, no es una buena opción.


¿Por qué una PhantomReference en lugar de una WeakReference?
uckelman 01 de

2
@uckelman: si todo lo que quieres es notificación, entonces PhantomReference hace el trabajo, para eso está diseñado. La semántica adicional de WeakReference no es necesaria aquí, y en el punto donde se notifica su ReferenceQueue, ya no puede recuperar el objeto a través de WeakReference, por lo que la única razón para usarlo es para evitar tener que recordar que existe PhantomReference. Cualquier trabajo adicional que haga WeakReference es probablemente insignificante, pero ¿por qué molestarse con él?
Steve Jessop

Gracias por insinuar PhantomReference. No es perfecto, pero aún mejor que nada.
foo

@SteveJessop, ¿qué "trabajo extra", cree usted, tiene una referencia débil en comparación con una referencia fantasma?
Holger

6

los finalize() función es el destructor.

Sin embargo, no debe usarse normalmente porque se invoca después del GC y no se puede saber cuándo sucederá (si es que lo hace).

Además, se necesita más de un GC para desasignar objetos que tienen finalize() .

¡Debería intentar limpiar en los lugares lógicos de su código usando las try{...} finally{...}declaraciones!


5

Estoy de acuerdo con la mayoría de las respuestas.

No debe depender completamente de ninguno finalizeoShutdownHook

finalizar

  1. La JVM no garantiza cuándo finalize()se invocará este método.

  2. finalize()se llama solo una vez por el hilo GC. Si un objeto se revive del método de finalización, finalizeno se volverá a llamar.

  3. En su aplicación, puede tener algunos objetos vivos, en los que nunca se invoca la recolección de basura.

  4. El Exceptionsubproceso GC ignora todo lo que arroje el método de finalización.

  5. System.runFinalization(true)y los Runtime.getRuntime().runFinalization(true)métodos aumentan la probabilidad de invocar el finalize()método, pero ahora estos dos métodos han quedado en desuso. Estos métodos son muy peligrosos debido a la falta de seguridad del hilo y la posible creación de puntos muertos.

shutdownHooks

public void addShutdownHook(Thread hook)

Registra un nuevo enlace de apagado de máquina virtual.

La máquina virtual Java se apaga en respuesta a dos tipos de eventos:

  1. El programa sale normalmente, cuando sale el último subproceso que no es daemon o cuando System.exitse invoca el método de salida (equivalente ), o
  2. La máquina virtual finaliza en respuesta a una interrupción del usuario, como escribir ^ C, o un evento de todo el sistema, como el cierre de sesión del usuario o el apagado del sistema.
  3. Un enlace de apagado es simplemente un subproceso inicializado pero no iniciado. Cuando la máquina virtual comienza su secuencia de apagado, iniciará todos los ganchos de apagado registrados en un orden no especificado y los dejará correr simultáneamente. Cuando todos los ganchos hayan terminado, ejecutará todos los finalizadores no invocados si se ha habilitado la finalización al salir.
  4. Finalmente, la máquina virtual se detendrá. Tenga en cuenta que los subprocesos de daemon continuarán ejecutándose durante la secuencia de apagado, al igual que los subprocesos que no son de daemon si el cierre se inició invocando el método de salida.
  5. Los ganchos de cierre también deberían terminar su trabajo rápidamente. Cuando un programa invoca la salida, se espera que la máquina virtual se apague y salga rápidamente.

    Pero incluso la documentación de Oracle citaba que

En raras circunstancias, la máquina virtual puede abortar, es decir, dejar de funcionar sin apagarse limpiamente

Esto ocurre cuando la máquina virtual se termina externamente, por ejemplo, con la SIGKILLseñal en Unix o la TerminateProcessllamada en Microsoft Windows. La máquina virtual también puede abortar si un método nativo falla, por ejemplo, corrompiendo las estructuras de datos internos o intentando acceder a la memoria inexistente. Si la máquina virtual aborta, no se puede garantizar si se ejecutarán o no ganchos de apagado.

Conclusión : use los try{} catch{} finally{}bloques adecuadamente y libere recursos críticos en finally(}bloque. Durante la liberación de recursos en finally{}bloque, captura Exceptiony Throwable.


4

Si solo te preocupa la memoria, no lo hagas. Solo confíe en el GC, hace un trabajo decente. De hecho, vi algo acerca de que es tan eficiente que podría ser mejor para el rendimiento crear montones de objetos pequeños que utilizar matrices grandes en algunos casos.


3

Quizás pueda usar un intento ... finalmente bloquee para finalizar el objeto en el flujo de control en el que está usando el objeto. Por supuesto, no sucede automáticamente, pero tampoco lo hace la destrucción en C ++. A menudo ve el cierre de recursos en el bloque finalmente.


1
Esta es la respuesta correcta cuando el recurso en cuestión tiene un único propietario y nunca tiene referencias a él "robadas" por otro código.
Steve Jessop

3

Hay una anotación @Cleanup en Lombok que se parece principalmente a los destructores de C ++:

@Cleanup
ResourceClass resource = new ResourceClass();

Al procesarlo (en el momento de la compilación), Lombok inserta el try-finallybloque apropiado para que resource.close()se invoque, cuando la ejecución abandona el alcance de la variable. También puede especificar explícitamente otro método para liberar el recurso, por ejemplo resource.dispose():

@Cleanup("dispose")
ResourceClass resource = new ResourceClass();

2
La ventaja que veo es que habrá menos anidamiento (lo que puede ser significativo si tiene muchos objetos que requieren "destrucción").
Alexey

Un bloque de prueba con recursos puede tener múltiples recursos de una sola vez
Alexander - Restablece a Mónica el

1
Pero no puede tener instrucciones entre ellos.
Alexey

Justa. Supongo que entonces la recomendación es preferir probar con recursos, incluso para múltiples recursos, a menos que haya que haber instrucciones entre ellos que lo obliguen a crear nuevos bloques de prueba con recursos (aumentar la anidación), luego usar@Cleanup
Alexander - Reinstalar Mónica

2

El equivalente más cercano a un destructor en Java es el método finalize () . La gran diferencia con un destructor tradicional es que no puedes estar seguro de cuándo será llamado, ya que es responsabilidad del recolector de basura. Recomiendo leer detenidamente esto antes de usarlo, ya que sus patrones RAIA típicos para identificadores de archivos, etc., no funcionarán de manera confiable con finalize ().


2

Aquí hay muchas respuestas excelentes, pero hay información adicional sobre por qué debería evitar usar finalize () .

Si la JVM se cierra debido a System.exit()o Runtime.getRuntime().exit(), los finalizadores no se ejecutarán de manera predeterminada. Desde Javadoc para Runtime.exit () :

La secuencia de apagado de la máquina virtual consta de dos fases. En la primera fase, todos los ganchos de apagado registrados, si los hay, se inician en un orden no especificado y se les permite ejecutarse simultáneamente hasta que terminen. En la segunda fase, todos los finalizadores no invocados se ejecutan si se ha habilitado la finalización al salir. Una vez hecho esto, la máquina virtual se detiene.

Puede llamar System.runFinalization()pero solo hace "un gran esfuerzo para completar todas las finalizaciones pendientes", no es una garantía.

Hay un System.runFinalizersOnExit()método, pero no lo use, es inseguro, está en desuso hace mucho tiempo.


1

Si está escribiendo un Applet Java, puede anular el método "destroy ()" del Applet. Está...

 * Called by the browser or applet viewer to inform
 * this applet that it is being reclaimed and that it should destroy
 * any resources that it has allocated. The stop() method
 * will always be called before destroy().

Obviamente no es lo que quieres, pero podría ser lo que otras personas están buscando.


1

Simplemente pensando en la pregunta original ... que, creo que podemos concluir de todas las otras respuestas aprendidas, y también de Java Efectivo esencial de Bloch , elemento 7, "Evitar finalizadores", busca la solución a una pregunta legítima de una manera que es inapropiado para el lenguaje Java ...:

... no sería una solución bastante obvia para hacer lo que realmente quiere el OP para mantener todos sus objetos que necesitan ser reiniciados en una especie de "corralito", al que todos los demás objetos no reiniciables tienen referencias solo a través de algún tipo del objeto de acceso ...

Y luego, cuando necesita "reiniciar", desconecta el corralito existente y crea uno nuevo: toda la red de objetos en el corralito se arroja a la deriva, nunca regresará, y un día será recogido por el GC.

Si alguno de estos objetos está Closeable(o no, pero tiene un closemétodo), puede colocarlos en un Bagcorralito a medida que se crean (y posiblemente se abren), y el último acto del descriptor de acceso antes de cortar el corralito sería ir a través de todo el Closeablescierre de ellos ...?

El código probablemente se vería así:

accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );

closeCloseablesprobablemente sería un método de bloqueo, probablemente con un pestillo (p CountdownLatch. ej. ), para tratar (y esperar según corresponda) cualquiera Runnables/ Callablesen cualquier subproceso específico para Playpenque finalice según corresponda, en particular en el subproceso JavaFX.


0

Aunque ha habido avances considerables en la tecnología GC de Java, aún debe tener en cuenta sus referencias. Me vienen a la mente numerosos casos de patrones de referencia aparentemente triviales que en realidad son nidos de ratas debajo del capó.

Desde su publicación, no parece que esté tratando de implementar un método de reinicio con el propósito de reutilizar objetos (¿verdad?). ¿Sus objetos contienen algún otro tipo de recursos que deben limpiarse (es decir, flujos que deben cerrarse, cualquier objeto agrupado o prestado que deba devolverse)? Si lo único que le preocupa es el acuerdo de memoria, entonces reconsideraría la estructura de mi objeto e intentaría verificar que mis objetos son estructuras autónomas que se limpiarán en el momento de la GC.



0

Ningún Java no tiene ningún destructor. La razón principal detrás de esto en Java son los recolectores de basura que siempre funcionan pasivamente en segundo plano y todos los objetos están hechos en la memoria de almacenamiento dinámico, ese es el lugar donde funciona GC. En C ++ allí tiene que llamar explícitamente a la función de eliminación, ya que no existe un recolector de basura similar.


-3

Solía ​​tratar principalmente con C ++ y eso es lo que también me llevó a buscar un destructor. Estoy usando mucho JAVA ahora. Lo que hice, y puede que no sea el mejor caso para todos, pero implementé mi propio destructor restableciendo todos los valores a 0 o por defecto a través de una función.

Ejemplo:

public myDestructor() {

variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL

}

Idealmente, esto no funcionará para todas las situaciones, pero donde haya variables globales funcionará siempre que no tenga un montón de ellas.

Sé que no soy el mejor programador de Java, pero parece estar funcionando para mí.


Trate de usar más objetos inmutables, después de que 'lo consiga' todo tendrá más sentido :)
R. van Twisk

55
Esto no está tan mal como no tiene sentido, es decir, no logra nada. Si su programa requiere que los tipos sin procesar se restablezcan para funcionar correctamente, entonces las instancias de sus clases tienen un alcance incorrecto, lo que significa que probablemente esté reasignando las propiedades de un objeto existente a las propiedades de un nuevo objeto, sin crear un nuevo Object ().
simo.3792

1
Excepto que hay muchas necesidades para restablecer variables. Elegí el nombre destructor porque se ajusta a lo que estoy haciendo. Lo hace lograr algo, nada a entender
ChristianGLong
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.