El tipo de retorno del constructor en Java

1. Información general

En este tutorial rápido, nos centraremos en el tipo de retorno de un constructor en Java.

Primero, nos familiarizaremos con cómo funciona la inicialización de objetos en Java y la JVM. Luego, profundizaremos para ver cómo funcionan bajo el capó la inicialización y asignación de objetos.

2. Inicialización de instancia

Comencemos con una clase vacía:

public class Color {}

Aquí, crearemos una instancia a partir de esta clase y la asignaremos a alguna variable:

Color color = new Color();

Después de compilar este simple fragmento de Java, echemos un vistazo a su código de bytes mediante el comando javap -c :

0: new #7 // class Color 3: dup 4: invokespecial #9 // Method Color."":()V 7: astore_1

Cuando creamos una instancia de un objeto en Java, la JVM realiza las siguientes operaciones:

  1. Primero, encuentra un lugar en su espacio de proceso para el nuevo objeto.
  2. Luego, la JVM realiza el proceso de inicialización del sistema. En este paso, crea el objeto en su estado predeterminado. El nuevo código de operación en el código de bytes es realmente responsable de este paso.
  3. Finalmente, inicializa el objeto con el constructor y otros bloques inicializadores. En este caso, el código de operación invocaespecial llama al constructor.

Como se muestra arriba, la firma del método para el constructor predeterminado es:

Method Color."":()V

los es el nombre de los métodos de inicialización de instancias en la JVM . En este caso, eles una función que:

  • no toma nada como entrada (paréntesis vacíos después del nombre del método)
  • no devuelve nada (V significa vacío )

Por lo tanto, el tipo de retorno de un constructor en Java y JVM es nulo.

Echando otro vistazo a nuestra sencilla tarea:

Color color = new Color();

Ahora que sabemos que el constructor devuelve vacío , veamos cómo funciona la asignación.

3. Cómo funciona la asignación

JVM es una máquina virtual basada en pilas. Cada pila consta de marcos de pila. En pocas palabras, cada marco de pila corresponde a una llamada a un método. De hecho, JVM crea marcos con una nueva llamada a método y los destruye cuando terminan su trabajo:

Cada marco de pila usa una matriz para almacenar variables locales y una pila de operandos para almacenar resultados parciales . Dado eso, echemos otro vistazo al código de bytes:

0: new #7 // class Color 3: dup 4: invokespecial #9 // Method Color."":()V 7: astore_1

Así es como funciona la tarea:

  • La nueva instrucción crea una instancia de Color y empuja su referencia a la pila de operandos
  • El código de operación dup duplica el último elemento de la pila de operandos
  • El invokespecial toma la referencia duplicada y la consume para la inicialización. Después de esto, solo la referencia original permanece en la pila de operandos
  • El astore_1 almacena la referencia original al índice 1 de la matriz de variables locales. El prefijo "a" significa que el elemento que se va a almacenar es una referencia de objeto y el "1" es el índice de la matriz.

De ahora en adelante, el segundo elemento (índice 1) en la matriz de variables locales es una referencia al objeto recién creado . Por lo tanto, no perdemos la referencia y la asignación realmente funciona, ¡incluso cuando el constructor no devuelve nada!

4. Conclusión

En este tutorial rápido, aprendimos cómo la JVM crea e inicializa nuestras instancias de clase. Además, vimos cómo funciona la inicialización de la instancia bajo el capó.

Para una comprensión aún más detallada de la JVM, siempre es una buena idea consultar su especificación.