天天看點

Integer類自動裝箱、拆箱與享元模式

       從JDK1.5開始java添加了一個新特性:自動裝箱和拆箱。這極大的簡化了簡單類型與包裝類型之間的轉換,那麼自動裝箱和拆箱是怎麼實作的呢?

現來看一行源代碼:

Integer a = 125;

用javap工具檢視其位元組碼為:

    0:  bipush  125

    2:  invokestatic  #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

     5:  astore_1

    可以發現Integer類的自動裝箱是通過調用類的靜态方法valueOf實作的。

閱讀Integer類的源代碼發現該類還用到了享元模式,對于範圍在-128~127的int類型數,不是新建立一個對象,而是傳回記憶體中已有的對象,對于不在此範圍裡的數則新建立一個對象。可以看一段代碼:

    Integer a = 125;

    Integer b = 125;

    System.out.println(a == b);

    Integer a1 = 128;

    Integer b1 = 128;

    System.out.println(a1 == b1);

輸出是:

true

false

這是怎麼實作的呢?

原因就在于在Integer類裡有個内隐類IntegerCache,存放-128~127範圍内的對應Integer類對象。

該類的靜态方法valueOf的實作是當數在此範圍之内時直接傳回内隐類IntegerCache中存放的對應的Integer類對象,否則用new新生成一個對象。這個就是設計模式中的享元模式吧。

那自動拆箱呢?

也先來看兩行代碼:

int b = a;

其位元組碼指令為:

     0:  bipush  125

     2:  invokestatic  #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

     6:  aload_1

     7:  invokevirtual  #22; //Method java/lang/Integer.intValue:()I

     10:  istore_2

     11:  return

可以看到自動拆箱是調用Integer類的成員方法intValue()實作的,而intValue方法就一行語句”傳回其value值。

繼續閱讀