2009-01-03 105 views

回答

44

您可以使用javap工具自行查看。編譯下面的代碼:

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

要編譯和拆卸:

javac AutoboxingTest.java 
javap -c AutoboxingTest 

的輸出是:

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 

} 

因此,可以看到,自動裝箱調用靜態方法Integer.valueOf(),和autounboxing在給定的Integer對象上調用intValue()。沒有別的,真的 - 它只是語法糖。

+1

有趣的是,它調用valueOf(int)而不是新的Integer(int)來將int轉換爲Integer。 valueOf對前1000個左右的整數進行對象緩存。 – 2009-01-04 02:13:13

1

我建議讓jad和反編譯代碼很多東西。你可以學習一些java實際上在做什麼。

9

我想出了一個單元測試,證明Integer.valueOf()被調用,而不是包裝器的構造函數。

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

如果您查找Integer#valueOf(int)的API文檔,您會發現它是在JDK 1.5中添加的。所有包裝類型(不包含它們)都添加了類似的方法來支持自動裝箱。對於某些類型有一個額外的需求,如在JLS描述:

如果值p被裝箱是truefalse,一個byte,在範圍內的char\u0000\u007f,或intshort-128127之間號碼,然後讓R1R2p的任何兩個裝箱轉換的結果。總是這樣的情況,即r1 == r2§5.1.7

很有趣的是,long s爲沒有受到同樣的要求,雖然在-128..127範圍長值Sun的實現緩存,就像其他整型。

我也是剛發現,我的The Java Programming Language副本,它說從\u0000\u00ffchar值緩存,當然,每個規範的上限爲\u007f(和Sun JDK符合規範在這種情況下) 。