自動(dòng)裝箱&自動(dòng)拆箱

自動(dòng)裝箱就是自動(dòng)將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝器類型;自動(dòng)拆箱就是自動(dòng)將包裝器類型轉(zhuǎn)換為基本數(shù)據(jù)類型。
需要裝箱拆箱的類型有:


包裝類型

對(duì)于基本數(shù)據(jù)類型,Java提供了對(duì)應(yīng)的包裹(wrap)類型。這些包裹類型將一個(gè)基本數(shù)據(jù)類型的數(shù)據(jù)轉(zhuǎn)換成對(duì)象的形式,從而使得它們可以像對(duì)象一樣參與運(yùn)算和傳遞。
上圖中的藍(lán)色方框即為java八種基本數(shù)據(jù)類型所對(duì)應(yīng)的包裝類型。
在第一周的打印基本類型的最大值最小值一題中我就用到了包裝類型:


向像Character有一些好用的方法,如Character.isDigit, Character.toLowerCase等;
練習(xí)自動(dòng)類型轉(zhuǎn)換,其實(shí)自動(dòng)裝箱和拆箱也很好理解,因?yàn)樗D(zhuǎn)換的類型是包裝類,將一個(gè)基本數(shù)據(jù)轉(zhuǎn)換為了類,所以稱為裝箱。

  • 舉例:
ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1); //自動(dòng)裝箱 int to Integer
intList.add(2); //自動(dòng)裝箱 int to Integer

int number = intList.get(0); // 自動(dòng)拆箱 Integer to int, numer = 1

自動(dòng)裝箱拆箱主要發(fā)生在賦值時(shí)和方法調(diào)用時(shí)。

自動(dòng)裝箱/拆箱的缺點(diǎn)

自動(dòng)裝箱/拆箱有一個(gè)問(wèn)題,那就是在一個(gè)循環(huán)中進(jìn)行自動(dòng)裝箱操作的情況,如下面的例子就會(huì)創(chuàng)建多余的對(duì)象,影響程序的性能。

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

在進(jìn)行沒(méi)一次的sum+=i運(yùn)算時(shí),都要先拆箱,再相加,然后又裝箱,相當(dāng)于:

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

注意的事項(xiàng)

對(duì)象相等比較

這是一個(gè)比較容易出錯(cuò)的地方,”==“可以用于原始值進(jìn)行比較,也可以用于對(duì)象進(jìn)行比較,當(dāng)用于對(duì)象與對(duì)象之間比較時(shí),比較的不是對(duì)象代表的值,而是檢查兩個(gè)對(duì)象是否是同一對(duì)象,這個(gè)比較過(guò)程中沒(méi)有自動(dòng)裝箱發(fā)生。進(jìn)行對(duì)象值比較不應(yīng)該使用”==“,而應(yīng)該使用對(duì)象對(duì)應(yīng)的equals方法。看下例:

public class AutoboxingTest {

    public static void main(String args[]) {

        // Example 1: == comparison pure primitive – no autoboxing
        int i1 = 1;
        int i2 = 1;
        System.out.println("i1==i2 : " + (i1 == i2)); // true

        // Example 2: equality operator mixing object and primitive
        Integer num1 = 1; // autoboxing
        int num2 = 1;
        System.out.println("num1 == num2 : " + (num1 == num2)); // true

        // Example 3: special case - arises due to autoboxing in Java
        Integer obj1 = 1; // autoboxing will call Integer.valueOf()
        Integer obj2 = 1; // same call to Integer.valueOf() will return same
                            // cached Object

        System.out.println("obj1 == obj2 : " + (obj1 == obj2)); // true

        // Example 4: equality operator - pure object comparison
        Integer one = new Integer(1); // no autoboxing
        Integer anotherOne = new Integer(1);
        System.out.println("one == anotherOne : " + (one == anotherOne)); // false

    }

}

例3和例4的結(jié)果之所以不同,我的結(jié)果是例3中聲明obj1和obj2 都為1,這個(gè)1是存在內(nèi)存棧的一個(gè)引用變量,指向內(nèi)存堆中為1的Integer對(duì)象,這個(gè)1就好像一個(gè)指針,指向內(nèi)存堆中同一個(gè)Integer的地址,因此例3結(jié)果為true;而例4使用關(guān)鍵字new聲明,聲明的oneanotherOne指向內(nèi)存堆中兩個(gè)不同的Integer對(duì)象,地址不同,因此用==比較是為false.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容