generic java autoboxing

java - generic - ¿Qué código genera el compilador para el autoboxing?



generic java (4)

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

  • El método valueOf () en el contenedor
  • El constructor de la envoltura
  • Alguna otra magia?

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


Puede usar la herramienta javap para verlo usted mismo. Compila el siguiente código:

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

Para compilar y desmontar:

javac AutoboxingTest.java javap -c AutoboxingTest

El resultado 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 a intValue() en el objeto Integer dado. No hay nada más, en realidad, es solo azúcar sintáctica.


Se me ocurrió una prueba unitaria que prueba que se llama Integer.valueOf () en lugar del constructor de la envoltura.

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 API doc para Integer # valueOf (int) , verá que se agregó en JDK 1.5. Todos los tipos de envoltura (que aún no los tenían) tenían métodos similares agregados para admitir el autoboxing. Para ciertos tipos, existe un requisito adicional, como se describe en el JLS:

Si el valor p que está siendo encasillado es true , false , un byte , un char entre el rango /u0000 a /u007f , o un número /u007f o short entre -128 y 127 , entonces r1 y r2 serán los resultados de dos conversiones de boxeo de p . Siempre es el caso que r1 == r2 . §5.1.7

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

También descubrí que en mi copia de The Java Programming Language , dice que los valores de char desde /u0000 hasta /u00ff están en caché, pero por supuesto el límite superior por la especificación es /u007f (y el Sun JDK cumple con las especificaciones de este caso).