java包裝類和值類型的關係

java包裝類總是讓人疑惑 它與值類型到底是怎麼樣一種關係? 本文將以int和Integer爲例來探討它們的關係

java值類型有int short char boolean byte long float double

除此之外的類型皆爲引用類型 引用類型和值類型的區別大家都很熟悉 在這裏就不多說了

引用類型和值類型有一個很重要的區別 那就是引用類型繼承Object類 值類型不是

而java很多泛型容器都要求類型繼承Object 調用虛方法要求必須是引用類型 很明顯這些值類型不滿足這個要求 怎麼辦? 包裝類應運而生

包裝類有Integer Short Char Boolean Byte Long Float Double和上文的值類型是對應的

既然包裝類是引用類型 那麼他就應該可以傳遞到別的方法被修改

[url=][/url]
publicstaticvoidchange(Integer a){    a *= 6;}publicstaticvoidmain(String[] args){    Integer integer =newInteger(5);    change(integer);    System.out.println(integer);}[url=][/url]

然而 以上程序輸出的結果是5 跟下文代碼的結果是相同的 這是爲什麼?

[url=][/url]
publicstaticvoidchange(inta){    a *= 6;}publicstaticvoidmain(String[] args) {   intinteger = 5;    change(integer);    System.out.println(integer);}[url=][/url]

這就得從包裝類的設計講起了 前文說過 包裝類是爲了能夠彌補值類型的缺陷而設計的

有了包裝類後 對於一個整數的表達就出現了int和Integer這兩個類型 一個是值類型一個是引用類型 這會讓程序員在使用過程中產生困擾

爲了消除這種困擾 java在設計時就儘可能地減少它們的區別 讓包裝類表現得如同值類型 於是就出現了上文的結果

這種區別減少是通過編譯器完成 如果我們查看編譯好的字節碼 就會看到上文的Integer其實是這樣工作的

[url=]

[/url]
publicstaticvoidchange(Integer a){    a = Integer.valueOf(a.intValue() * 6);}publicstaticvoidmain(String[] args){    Integer integer =newInteger(5);    change(integer);    System.out.println(integer);}[url=]

[/url]

a*=6的結果返回了一個新的Integer對象

所以也就不可能修改傳入的Integer的值了 就算要修改   Integer這個類的成員是final修飾 還是無法修改

然後我還發現了一點Object強制轉換爲int

Object obj =newInteger(5);inta = (int)obj;

在編譯器處理後 其實是這樣的 這也進一步說明引用類型和值類型完全是兩個世界的東西

Object obj =newInteger(5);inta = ((Integer)obj).intValue();

題外話:

對於java的值類型和包裝類的設計 我十分不喜歡

java中一切都是對象 值類型除外

對於同樣一個整數類型 分成int Interger兩個類型感覺很沒必要

c#的int是繼承Object的 在需要調用虛函數的時候會自動裝箱

inta =233;a.ToString()

在jvm上跑的Kotlin 它有一套特殊映射法則 把Int根據情況自動變換成int和Integer 而在語言層面上只有一個Int

Int a = 233;a.toString();

但是到了java 你只能這樣

inta = 233;newInteger(a).toString();

或者是這樣

inta = 233;((Integer)a).toString();

參考黑馬資料教程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章