Múltiples instancias del mismo objeto


8

¿Qué sucede exactamente en Java cuando crea una instancia del mismo objeto varias veces?

Por ejemplo:

Test test = new Test();

luego lo llamaré nuevamente, Test test = new Test();nuevamente o dentro de un bucle. ¿Se eliminará la instanciación anterior?

Respuestas:


16
  1. cada llamada new Test()crea una nueva instancia de objeto de la Testclase
  2. test = new Test();asigna una referencia de ese objeto a la variabletest
  3. Una instrucción repetida test = new Test()crea una segunda instancia Testy asigna la referencia a la variable testnuevamente, por lo que se reemplaza la primera referencia.

Si y cuándo se eliminará la primera instancia, sin embargo, depende. El entorno de tiempo de ejecución Java rastrea referencias, por lo que siempre que haya referencias a un objeto en uso, el objeto no se eliminará. Por ejemplo, si entre el paso 2 y el paso 3, la referencia a la primera instanciación se almacena en otro lugar (como Test test2 = test;), y esa variable todavía está dentro del alcance cuando se produce el paso 3, entonces el primer objeto no está dispuesto, ya test2que todavía contiene una referencia lo. Sin embargo, cuando no existe tal declaración y el paso 3 omite la referencia única al primer objeto, entonces se eliminará ese objeto.

Tenga en cuenta que la eliminación en sí no ocurre inmediatamente, pero a veces más tarde, la próxima vez que se ejecuta el recolector de basura. Pero eso es independiente de la semántica del código discutido, eso es solo una cuestión de memoria y rendimiento.


44
La JVM no hace recuento de referencias. Hablando estrictamente, la especificación no exige cómo (o incluso eso) se implementa la recolección de basura, pero todas las JVM convencionales usan algún tipo de recolector de rastreo.
Michael Borgwardt

@MichaelBorgwardt: cambió mi respuesta debido a tu comentario.
Doc Brown

if between step 2 and step 3 the reference to the first instantiation is stored somewhere else (like Test test2 = test;), and that variable is still in scope when step 3 occurs...Esto es algo pedante, pero la recolección de basura no se basa en el alcance, sino en la accesibilidad. Es posible que una variable esté dentro del alcance, pero su valor ya no se usa, y ese valor puede recolectarse basura. Los recolectores de basura no tienen ámbitos a mano para tomar decisiones basadas en eso.
Doval

@Doval: Estoy de acuerdo, este comentario es pedante ;-)
Doc Brown

5

1: Algunas palabras: no instanciamos objetos en absoluto, instanciamos clases, y el producto de una instanciación de clase es un objeto (también llamado instancia). Por supuesto, podemos crear una instancia de una clase tantas veces como sea necesario para crear un objeto nuevo y diferente con cada instanciación.

2: Lo que sea, no puede tener el código que sugiere:

Test test = new Test();
Test test = new Test();

tampoco puedes tener esto:

for (i=0; i<3; i++) {
    Test test = new Test();
    Test test = new Test();
}

Ninguno compilará, porque la parte Test testes la declaración de variable test(de tipo Test), y ningún lenguaje, incluido Java, permite declarar dos veces la misma variable en el mismo ámbito.

Sin embargo, puede asignar varias veces la misma variable (como su nombre lo indica), con diferentes objetos, como este:

Test test = new Test();
test = new Test();

La primera línea declara testy le asigna un objeto recién creado. La segunda línea se asigna a testotro objeto, también recién creado.

También tenga en cuenta que los accesos directos están permitidos en Java:

for (i=0; i<3; i++) {
    Test test = new Test();
}

Este bucle no se declarará test3 veces. Se entiende como asignar tres nuevos objetos diferentes en secuencia a la variable testque se declarará solo una vez. (comparar con el bucle anterior).

3: ¿Qué le sucede a la variable testy a los dos objetos de tipo Test?

A la variable testprimero se le asigna la referencia de un objeto, luego de otro objeto. Una variable retiene solo la última referencia asignada.

El primer objeto de tipo Testya no está asignado test. Si a ninguna otra variable se le ha asignado su referencia, el programa no puede acceder a este objeto de ninguna manera y, por lo tanto, es inútil. El sistema lo hace elegible para la recolección de basura. En algún momento el sistema (la JVM) ejecutará su recolector de basura que lo borrará de la memoria.

El segundo objeto vivirá mientras al menos una variable lo haga referencia, luego el recolector de basura también lo cuidará y lo llevará al Cementerio de objetos sin referencia. Esa es la verdadera vida de los objetos Java :-(


Por casualidad encontré ese error en una clase. Las clases tienen una propiedad declarada como: WindowManager wm = new WindowsManager (); y luego un método en el que el programador estaba usando esta propiedad pero escribió por error: WindowManager wm = new WindowsManager (); de nuevo. ¡No solo se compiló, sino que también se ejecutó! Sin advertencia alguna y, por supuesto, la aplicación, que es una prueba, no funcionaba bien. Luego me di cuenta de que estaba creando el objeto dentro del alcance del método y la propiedad nunca fue modificada. Así que ten cuidado
Ricker Silva

1
Como explicaste perfectamente, esto no es una reasignación de la misma variable. Un error sombreado similares puede ocurrir cuando se utiliza un parámetro si olvida la thispalabra clave, al igual que en los constructores: this.name = name.
minutos

-1

Respuesta corta: todos los objetos creados previamente se eliminarán si nadie los señala. Solo existirá el más reciente porque la prueba lo hace referencia.

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.