2009-01-03 9 views

Respuesta

44

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

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

para compilar y desmonte:

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 se puede ver, autoboxing invoca el método estático Integer.valueOf(), y autounboxing invoca intValue() en el objeto dado Integer. No hay nada más, en realidad, es solo azúcar sintáctica.

+1

Es interesante observar que llama a valueOf (int) en lugar de nuevo entero (int) para convertir int a Integer. valueOf hace caché de objetos para los primeros 1000 o tan enteros. –

+3

-128 a 127 están en caché –

+0

@Craig: para ser precisos, -128 a 127 ** debe ** estar en caché, otros valores pueden ser almacenados en caché por una implementación. –

1

Recomiendo obtener algo así como jad y código de descompilación mucho. Puedes aprender bastante sobre lo que java está haciendo en realidad.

9

Se me ocurrió una prueba unitaria que prueba que se llama 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); 
    } 
} 
4

Si usted busca la documentación del API para Integer#valueOf(int), verá que se añadió en el 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 hay un requisito adicional, como se describe en el JLS:

Si el valor p siendo en caja es true, false, un byte, un char en el intervalo \u0000 a \u007f, o un int o short número entre -128 y 127, y luego dejar r1 y r2 ser los resultados de las 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 a los mismos requisitos, aunque los valores largos en la gama -128..127 se almacenan en caché en la implementación de Sun, al igual que los otros tipos integrales.

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

Cuestiones relacionadas