Pregunta

Cuando el compilador de Java hace un autobox de una primitiva a la clase contenedora, ¿qué código genera detrás de escena? Me imagino que llama:

  • El método valueOf () en la envoltura
  • El constructor de la envoltura
  • ¿Alguna otra magia?
¿Fue útil?

Solución

Puedes usar la herramienta javap para ver por ti mismo. Compila el siguiente código:

public class AutoboxingTest
{
    public static void main(String []args)
    {
        Integer a = 3;
        int b = a;
    }
}

Para compilar y desensamblar:

javac AutoboxingTest.java
javap -c AutoboxingTest

La salida es:

Compiled from "AutoboxingTest.java"
public class AutoboxingTest extends java.lang.Object{
public AutoboxingTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_3
   1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   4:   astore_1
   5:   aload_1
   6:   invokevirtual   #3; //Method java/lang/Integer.intValue:()I
   9:   istore_2
   10:  return

}

Por lo tanto, como puede ver, el autoboxing invoca el método estático Integer.valueOf () , y autounboxing invoca intValue () en el Integer dado objeto. En realidad, no hay nada más, solo es azúcar sintáctica.

Otros consejos

Se me ocurrió una prueba de unidad que prueba que se llama a Integer.valueOf () en lugar del constructor del envoltorio.

import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import org.junit.Test;

public class Boxing {
    @Test
    public void boxing() {
        assertSame(5, 5);
        assertNotSame(1000, 1000);
    }
}

Si busca el documento API para Integer # valueOf (int) , verá que se agregó en JDK 1.5. Todos los tipos de envoltorios (que aún no los tenían) tenían métodos similares agregados para admitir el autoboxing. Para ciertos tipos hay un requisito adicional, como se describe en el JLS:

  

Si el valor p que está en el recuadro es true , false , un byte , un char en el rango \ u0000 a \ u007f , o un int o corto entre -128 y 127 , luego deje que r1 y r2 sean los resultados de cualquiera de las dos conversiones de boxeo de p . Siempre es el caso que r1 == r2 . & # 167; 5.1.7

Es interesante observar que los long no están sujetos al mismo requisito, aunque los valores Long en el rango -128..127 se almacenan en caché en la implementación de Sun, Al igual que los otros tipos integrales.

También acabo de descubrir que en mi copia de El Java Programming Language , dice que los valores de char de \ u0000 a \ u00ff se almacenan en caché, pero por supuesto el límite superior por la especificación es \ u007f (y el Sun JDK cumple con la especificación en este caso).

Recomiendo obtener algo como jad y descompilar mucho el código. Puedes aprender bastante sobre lo que Java está haciendo realmente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top