Java中的拆箱和裝箱

來源:互聯網
上載者:User

標籤:top   int操作   png   val   對象   工作   center   建立   數組   

首先說一下Java中的封裝類,Java語言是一個物件導向的語言,但是Java中的基礎資料型別 (Elementary Data Type)卻不是物件導向的,這在實際使用時存在很多的不便(比如,我們不能直接想集合Collections中放入原始類型值,因為集合只接收對象)。為瞭解決這個不足,在設計類的是為每個基礎資料型別 (Elementary Data Type)設計了一個對應的類進行代表,這樣八個和基礎資料型別 (Elementary Data Type)對應的類統稱為封裝類(Wrapper Class)。

基礎資料型別 (Elementary Data Type)

封裝類

byte

Byte

boolean

Boolean

short

Short

char

Character

int

Integer

long

Long

float

Float

double

Double

自動裝箱就是Java自動將原始類型轉化為對應的對象,比如將int的變數轉化為Integer對象,這個過程叫做裝箱,反之將Integer對象轉化為int對象,這個過程叫做拆箱。又因為這個過程是自動發生的,所以又叫自動裝箱,自動拆箱。

ArrayList<Integer> arrayList = new ArrayList<Integer>();arrayList.add(1);  //自動裝箱 int --> Integerint number = arrayList.get(0);     //自動拆箱   Integer  -->  int

 

簡單點說,裝箱就是自動將基本類型轉化為封裝類型,拆箱就是自動將封裝類型轉化為基本類型。

在自動裝箱的過程中,系統為我們執行了

Integer total = Integer.valueOf(1);

 自動拆箱的過程中,系統為我們執行了

int number = total.intValue();

弊端:

  有些情況中,自動裝箱如果不注意的話會建立多餘的對象,影響程式的效能。

Integer sum = 0; for(int i=1000; i<5000; i++){   sum+=i;}

  上述代碼中 sum+=i 可以看成 sum = sum +i,但是這個 + 操作符不適用與Integer對象,首先sum進行自動拆箱操作,進行數值的相加操作,最後發生自動裝箱操作轉化為Integer對象。

其內部的變化如下:

sum = sum.intValue() + i;Integer sum = new Integer(result);

由於我們聲明的sum為Integer類型,在上面的迴圈中會建立將近4000個無用的對象,在這樣龐大的迴圈中,會降低程式的效能並且加重了記憶體回收的工作量。因此在我們編程時,需要注意到這一點,正確的聲明變數類型,避免因為自動裝箱引起的效能問題。

  在Integer類內部包含了一些和int操作有關的方法,下面介紹一些比較常用的方法:

  a、parseInt方法

                            public static int parseInt(String s)

該方法的作用是將數字字串轉換為int數值。在以後的介面編程中,將字串轉換為對應的int數字是一種比較常見的操作。使用樣本如下:

                                     String s = “123”;

                                     int n = Integer.parseInt(s);

則int變數n的值是123,該方法實際上實現了字串和int之間的轉換,如果字串都包含的不是都是數字字元,則程式執行將出現異常。

另外一個parseInt方法:

         public static int parseInt(String s, int radix)

則實現將字串按照參數radix指定的進位轉換為int,使用樣本如下:

         //將字串”120”按照十進位轉換為int,則結果為120

         int n = Integer.parseInt(“120”,10);

         //將字串”12”按照十六進位轉換為int,則結果為18

         int n = Integer.parseInt(“12”,16);

         //將字串”ff”按照十六進位轉換為int,則結果為255

         int n = Integer.parseInt(“ff”,16);

這樣可以實現更靈活的轉換。

                   b、toString方法

                            public static String toString(int i)

                            該方法的作用是將int類型轉換為對應的String類型。

                            使用範例程式碼如下:

                                     int m = 1000;

                                     String s = Integer.toString(m);

                            則字串s的值是”1000”。

                            另外一個toString方法則實現將int值轉換為特定進位的字串:

                                     public static int parseInt(String s, int radix)

                            使用範例程式碼如下:

                                     int m = 20;

                                     String s = Integer.toString(m);

                            則字串s的值是”14”。

另外說一個前兩天遇到的問題

  int i = Integer.valueOf("222");        System.out.println(i);

在用findbugs查到了這個問題,進行了多餘的拆箱和裝箱操作,原因是 Interger.valuesOf("")返回的是 Integer對象,然後再拆箱到 int類型。

看幾個例子

        int i = 128;        Integer i2 = 128;        Integer i3 = new Integer(128);        //Integer會自動拆箱為int,所以為true        System.out.println(i == i2);  //true        System.out.println(i == i3);  //true        System.out.println("**************");        System.out.println(i2 == i3);  //false        Integer i5 = 127;//java在編譯的時候,被翻譯成-> Integer i5 = Integer.valueOf(127);        Integer i6 = 127;        System.out.println(i5 == i6);//true        /*Integer i5 = 128;        Integer i6 = 128;        System.out.println(i5 == i6);//false*/        Integer ii5 = new Integer(127);        System.out.println(i5 == ii5); //false        Integer i7 = new Integer(127);        Integer i8 = new Integer(123);        System.out.println(i7 == i8);  //false

  總結一下就是如果 Integer 和int類型相比,那麼會將Integer類型拆箱為int類型的然後進行數值比較,如果是 Integer i = new Integer (127);這種會建立新的 Integer對象,所以實際對比的是兩個對象,基本會返回false(當然如果和int類型相比也是返回 數值比較結果)。如果 是 Integer i1 = 127,Integer i2 = 127,這種比較的話,如果小於128 會返回true,大於等於128 會返回false。

為什麼會出現這樣呢,上面說到 integer i = 127, 會執行裝箱操作,實際上 是執行了 Integer.valueOf(127),我們看一下 valueOf函數

public static Integer valueOf(int i) {    return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];}

 它會首先判斷i的大小:如果i小於-128或者大於等於128,就建立一個Integer對象,否則執行SMALL_VALUES[i + 128]。

private static final Integer[] SMALL_VALUES = new Integer[256];

它們的值在(-128,128]這個範圍內,它們會拿到SMALL_VALUES數組裡面的同一個對象SMALL_VALUES[228],它們引用到了同一個Integer對象。

Java中的拆箱和裝箱

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.