¿Qué código genera el compilador para autoboxing?
-
03-07-2019 - |
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?
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
, unbyte
, unchar
en el rango\ u0000
a\ u007f
, o unint
ocorto
entre-128
y127
, 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.