首頁  >  文章  >  Java  >  淺談什麼是java的自動裝箱和自動拆箱?

淺談什麼是java的自動裝箱和自動拆箱?

青灯夜游
青灯夜游轉載
2018-10-19 17:43:022661瀏覽

本篇文章帶給大家的內容是淺談什麼是java的自動裝箱和自動拆箱?有一定的參考價值,有需要的朋友可以參考一下,希望對你們有幫助。

自動拆箱和自動包裝器

#Java為每個基本資料類型都提供了對應的包裝器類型。舉個例子:

public class TestMain
{
    public static void main(String[] args)
    {
        Integer i = 10;
    }
}

這個過程中會自動根據數值建立對應的Integer對象,這就是自動裝箱。再看另外一段程式碼:

public class TestMain
{
    public static void main(String[] args)
    {
        Integer integer = 10;
        int i = integer;
    }
}

這個過程中會根據包裝器類型自動將資料轉換為基本型別,這就是自動拆箱。

至於自動裝箱和自動拆箱的原理也很簡單。透過命令列程序,進入CLASSPATH(也就是bin目錄下.class檔案所在的路徑),javap反編譯查看一下產生的字節碼:

反編譯出來的內容很多,我們只專注在重點部分:

public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=1
         0: iconst_1
         1: invokestatic  #16                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
         4: astore_1
         5: aload_1
         6: invokevirtual #22                 // Method java/lang/Integer.intVal
ue:()I
         9: istore_2
        10: return

看到在自動裝箱的時候#,Java虛擬機會自動呼叫Integer的valueOf方法;在自動拆箱的時候Java虛擬機會自動呼叫Integer的intValue方法這就是自動拆箱和自動裝箱的原理

小心空指標異常

有這麼一段程式碼:

public static void main(String[] args) throws Exception
{
    Object obj = getObj(null);
    int i = (Integer)obj;
}
    
public static Object getObj(Object obj)
{
    return obj;
}

這種使用場景很常見,我們把一個int數值放在session或request中,取出來的時候就是一個類似上面的場景了。所以,小心自動拆箱時候的空指標異常。

小陷阱

看兩段程式碼,第一段程式碼為:

public class TestMain
{
    public static void main(String[] args)
    {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;
        
        System.out.println(i1 == i2);
        System.out.println(i3 == i4);
    }
}

運行結果為:

true
false

第二段程式碼為:

public class TestMain
{
    public static void main(String[] args)
    {
        Double d1 = 100.0;
        Double d2 = 100.0;
        Double d3 = 200.0;
        Double d4 = 200.0;
        
        System.out.println(d1 == d2);
        System.out.println(d3 == d4);
    }
}

執行結果為:

false
false

產生這樣的結果的原因是:Byte、Short、Integer、Long、Char這幾個裝箱類別的valueOf()方法是以128位元分界線做了快取的,假如是128以下且-128以上的值是會取快取裡面的引用的,以Integer為例,其valueOf(int i)的原始碼為:

public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
    }
        return new Integer(i);
    }

而Float、Double則不會,原因也很簡單,因為byte、Short、integer、long、char在某個範圍內的整數個數是有限的,但是float、double這兩個浮點數卻不是。

總結:以上就是這篇文章的全部內容,希望能對大家的學習有所幫助。更多相關教學請造訪Java影片教學java開發圖文教學bootstrap影片教學

以上是淺談什麼是java的自動裝箱和自動拆箱?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除