java自動裝箱拆箱深入剖析

來源:互聯網
上載者:User

這個是jdk1.5以後才引入的新的內容,作為秉承發表是最好的記憶,毅然決定還是用一篇部落格來代替我的記憶:
java語言規範中說道:在許多情況下封裝與解封裝是由編譯器自行完成的(在這種情況下封裝成為裝箱,解封裝稱為拆箱);
其實按照我自己的理解自動裝箱就可以簡單的理解為將基礎資料型別 (Elementary Data Type)封裝為物件類型,來符合java的物件導向;例如用int來舉例:

複製代碼 代碼如下://聲明一個Integer對象
Integer num = 10;
//以上的聲明就是用到了自動的裝箱:解析為
Integer num = new Integer(10);以上就是一個很好的體現,因為10是屬於基礎資料型別 (Elementary Data Type)的,原則上它是不能直接賦值給一個對象Integer的,但jdk1.5後你就可以進行這樣的聲明,這就是自動裝箱的魅力
自動將基礎資料型別 (Elementary Data Type)轉化為對應的封裝類型。成為一個對象以後就可以調用對象所聲明的所有的方法
自動拆箱:故名思議就是將對象重新轉化為基礎資料型別 (Elementary Data Type):
//裝箱
Integer num = 10;
//拆箱
int num1 = num;自動拆箱有個很典型的用法就是在進行運算的時候:因為對象時不恩直接進行運算的,而是要轉化為基礎資料型別 (Elementary Data Type)後才能進行加減乘除
Integer num = 10;
//進行計算時隱含的有自動拆箱
System.out.print(num--);哈哈 應該感覺很簡單吧,下面我再來講點稍微痛點的,
//在-128~127 之外的數
Integer num1 = 297; Integer num2 = 297;
System.out.println("num1==num2: "+(num1==num2));
// 在-128~127 之內的數
Integer num3 = 97; Integer num4 = 97;
System.out.println("num3==num4: "+(num3==num4)); 列印的結果是:num1==num2: false num3==num4: true

很奇怪吧:這就歸結於java對於Integer與int的自動裝箱與拆箱的設計,是一種模式:叫享元模式(flyweight)
為了加大對簡單數位重利用,java定義:在自動裝箱時對於值從–128到127之間的值,它們被裝箱為Integer對象後,會存在記憶體中被重用,始終只存在一個對象
而如果超過了從–128到127之間的值,被裝箱後的Integer對象並不會被重用,即相當於每次裝箱時都建立一個 Integer對象;明白了吧
以上的現象是由於使用了自動裝箱所引起的,如果你沒有使用自動裝箱,而是跟一般類一樣,用new來進行執行個體化,就會每次new就都一個新的對象;
這個的自動裝箱拆箱不僅在基礎資料型別 (Elementary Data Type)中有應用,在String類中也有應用,比如我們經常聲明一個String對象時: 複製代碼 代碼如下:String str = "sl";
//代替下面的聲明方式
String str = new String("sl");

基本資料(Primitive)類型的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。雖然為您打包基礎資料型別 (Elementary Data Type)提供了方便,但提供方便的同時表示隱藏了細節,建議在能夠區分基礎資料型別 (Elementary Data Type)與對象的差別時再使用。
autoboxing和unboxing
在Java中,所有要處理的東西幾乎都是對象 (Object),例如之前所使用的Scanner是對象,字串(String)也是對象,之後還會看到更多的對象。然而基本(Primitive)資料類型不是對象,也就是您使用int、double、boolean等定義的變數,以及您在中直接寫下的字面常量。
在前一個小節中已經大致看到了操作對象的方便性,而使用Java有一段時間的人都知道,有時需要將基礎資料型別 (Elementary Data Type)轉換為對象。例如使用Map對象要put()方法時,需要傳入的參數是對象而不是基礎資料型別 (Elementary Data Type)。
要使用打包類型(Wrapper Types)才能將基礎資料型別 (Elementary Data Type)封裝為對象,前一個小節中您已經知道在J2SE 5.0之前,要使用以下語句才能將int封裝為一個Integer對象:Integer integer = new Integer(10);
在 J2SE 5.0之後提供了自動裝箱的功能,您可以直接使用以下語句來打包基礎資料型別 (Elementary Data Type):Integer integer = 10;
在進行編譯時間,編譯器再自動根據您寫下的語句,判斷是否進行自動裝箱動作。在上例中integer參考的會是Integer類的執行個體。同樣的動作可以適用於 boolean、byte、short、char、long、float、double等基礎資料型別 (Elementary Data Type),分別會使用對應的打包類型(Wrapper Types)Boolean、Byte、Short、Character、Long、Float或Double。下面直接使用自動裝箱功能來改寫範例 4.4。

範例4.5 AutoBoxDemo.java 複製代碼 代碼如下:public class AutoBoxDemo {
public static void main(String[] args) {
Integer data1 = 10;
Integer data2 = 20;
// 轉為double值再除以3
System.out.println(data1.doubleValue() / 3);
// 進行兩個值的比較
System.out.println(data1.compareTo(data2));
}
}

程式看來簡潔了許多,data1與data2在運行時就是Integer的執行個體,可以直接進行對象操作。的結果如下:
3.3333333333333335
–1
自動裝箱運用的方法還可以如下: 複製代碼 代碼如下:int i = 10;
Integer integer = i;

也可以使用更一般化的java.lang.Number類來自動裝箱。例如:
Number number = 3.14f;
3.14f會先被自動裝箱為Float,然後指定給number。
從J2SE 5.0開始可以自動裝箱,也可以自動拆箱(unboxing),也就是將對象中的基本資料形態資訊從對象中自動取出。例如下面這樣寫是可以的: 複製代碼 代碼如下:Integer fooInteger = 10;
int fooPrimitive = fooInteger;

fooInteger引用至自動裝箱為Integer的執行個體後,如果被指定給一個int類型的變數fooPrimitive,則會自動變為int類型再指定給fooPrimitive。在運算時,也可以進行自動裝箱與拆箱。例如: 複製代碼 代碼如下:Integer i = 10;
System.out.println(i + 10);
System.out.println(i++);

上例中會顯示20與10,編譯器會自動進行自動裝箱與拆箱,也就是10會先被裝箱,然後在i + 10時會先拆箱,進行加法運算;i++該行也是先拆箱再進行遞增運算。再來看一個例子: 複製代碼 代碼如下:Boolean boo = true;
System.out.println(boo && false);

同樣的boo原來是Boolean的執行個體,在進行AND運算時,會先將boo拆箱,再與false進行AND運算,結果會顯示false。
//////////////////////////////////////////////////////////////////
裝箱:從基本類型轉換成Object類型,稱之為裝箱;***拆箱:從Object轉轉乘基本類型的操作,稱之為拆箱。 這個操作在反射過程中用的比較的多。
裝箱:在堆中建立一個Object執行個體,把你指定的值複製成去;***拆箱:判別引用指向的堆中資訊是否是要拆成的類型,是取出堆中值送給棧中變數,否則報異常
///////////////////////////////////////////////////////////////////
裝箱是實值型別到object類型或到該實值型別所實現的任何介面類型的隱士轉換。
將一個實值型別裝箱會分配一個對象執行個體並將該值複製到新的對象中。 複製代碼 代碼如下:int i=123;
object o=i;

這句話的結果是在堆棧上建立一個對象o,而該對象在堆上引用int類型的值。該值是賦值給變數i
的實值型別值的一個副本。
下面是顯示執行裝箱轉換 複製代碼 代碼如下:int i=123;
ojbect o=(object)i;

此例將整數變數i通過裝箱轉換為對象o。這樣,儲存在變數i中的值就從123改為456。此例顯示對象保留了內容的原始副本。即123。
unboxing是從object類型到實值型別或從介面類型到實現該介面的實值型別的顯示轉換。unboxing操作包括:
檢查對象執行個體,確保它是給定實值型別的一個裝箱值。
將該值從執行個體複製到實值型別變數中。
例子: 複製代碼 代碼如下:int i=123;
object box=i;
int j=(int)box;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.