<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在 Java 中,萬物皆物件,所有的操作都要求用物件的形式進行描述。但是 Java 中除了物件(參照型別)還有八大基本型別,它們不是物件。那麼,為了把基本型別轉換成物件,最簡單的做法就是將基本型別作為一個類的屬性儲存起來,也就是把基本資料型別包裝一下,這也就是包裝類的由來。
這樣,我們先自己實現一個簡單的包裝類,以包裝基本型別 int
為例:
// 包裝類 MyInt public class MyInt { private int number; // 基本資料型別 public Int (int number){ // 建構函式,傳入基本資料型別 this.number = number; } public int intValue(){ // 取得包裝類中的資料 return this.number; } }
測試一下這個包裝類:
public static void main(String[] args) { MyInt temp = new Int(100); // 100 是基本資料型別, 將基本資料型別包裝後成為物件 int result = temp.intValue(); // 從物件中取得基本資料型別 System.out.println(result); }
當然,我們自己實現的這個包裝類非常簡單,Java 給我們提供了更完善的內建包裝類:
基本型別 | 對應的包裝類(位於 java.lang 包中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
前 6 個類派生於公共的超類 Number
,而 Character
和 Boolean
是 Object
的直接子類。
來看看包裝類的宣告,以 Integer
為例:
被 final
修飾,也就是說 Java 內建的包裝類是無法被繼承的。
OK,現在我們已經知道了,存在基本資料型別與其對應的包裝類,那麼,他們之間互相的轉換操作就稱為裝箱與拆箱:
下面以 Integer
為例,我們來看看 Java 內建的包裝類是如何進行拆裝箱的:
Integer obj = new Integer(10); // 自動裝箱 int temp = obj.intValue(); // 自動拆箱
可以看出,和上面我們自己寫的包裝類使用方式基本一樣,事實上,Integer
中的這兩個方法其底層實現和我們上述寫的程式碼也是差不多的。
不知道各位發現沒,value
被宣告為 final
了,也就是說一旦構造了包裝器,就不允許更改包裝在其中的值。
另外,需要注意的是,這種形式的程式碼是 JDK 1.5 以前的!!!JDK 1.5 之後,Java 設計者為了方便開發提供了自動裝箱與自動拆箱的機制,並且可以直接利用包裝類的物件進行數學計算。
還是以 Integer
為例我們來看看自動拆裝箱的過程:
Integer obj = 10; // 自動裝箱. 基本資料型別 int -> 包裝類 Integer int temp = obj; // 自動拆箱. Integer -> int obj ++; // 直接利用包裝類的物件進行數學計算 System.out.println(temp * obj);
看見沒有,基本資料型別到包裝類的轉換,不需要像上面一樣使用建構函式,直接 =
就完事兒;同樣的,包裝類到基本資料型別的轉換,也不需要我們手動呼叫包裝類的 xxxValue 方法了,直接 =
就能完成拆箱。這也是將它們稱之為自動的原因。
我們來看看這段程式碼反編譯後的檔案,底層到底是什麼原理:
Integer obj = Integer.valueOf(10); int temp = obj.intValue();
可以看見,自動裝箱的底層原理是呼叫了包裝類的 valueOf
方法,而自動拆箱的底層呼叫了包裝類的 intValue()
方法。
我們上面已經看過了用於自動拆箱的 intValue
方法的原始碼,非常簡單。接下來咱來看看用於自動裝箱的 valueOf
,其他包裝類倒沒什麼好說的,不過 Integer
中的這個方法還是有點東西的:
IntegerCache
又是啥,點進去看看:
IntegerCache
是 Integer
類中的靜態內部類,綜合這兩段程式碼,我們大概也能知道,IntegerCache
其實就是個快取,其中定義了一個緩衝區 cache
,用於儲存 Integer
型別的資料,快取區間是 [-128, 127]。
回到 valueOf
的原始碼:它首先會判斷 int 型別的實參 i 是否在可快取區間內,如果在,就直接從快取 IntegerCache
中獲取對應的 Integer
物件;如果不在快取區間內,則會 new 一個新的 Integer
物件。
結合這個特性,我們來看一個題目,兩種類似的程式碼邏輯,但是卻得到完全相反的結果。:
public static void main(String args[]) { Integer a1 = 127; Integer a2 = 127; System.out.println(a1 == a2); // true Integer b1 = 128; Integer b2 = 128; System.out.println(b1 == b2); // false }
我們知道,==
擁有兩種應用場景:
從 a1 開始看,由於其值在 InterCache
的快取區間內,所以這個 Integer
物件會被存入快取。而在建立 a2 的時候,由於其值和 a1 相等,所以直接從快取中取出值為 127 的 Integer
物件給 a2 使用,也就是說,a1 和 a2 這兩個 Integer
的物件參照都指向同一個地址。
對於 b1 和 b2 來說,由於 128 不在 IntegerCache
的快取區間內,那就只能自己老老實實開闢空間了,所以 b1 和 b2 指向不同的記憶體地址。
很顯然,由於 InterCache
快取機制的存在,可能會讓我們在程式設計的時候出現困惑,因此最好使用 .equals
方法來比較 Integer
值是否相等。Integer
重寫了 .equals
方法:
當然,其他包裝類雖然沒有快取機制,但是也都過載了 .equals
方法,用於根據值來判斷是否相等。因此,得出結論,使用 equals
方法來比較兩個包裝類物件的值。
綜上,有了自動拆裝箱機制,基本資料型別可以自動的被轉為包裝類,而 Object
是所有類的父類別,也就是說,Object
可以接收所有的資料型別了(參照型別、基本型別)!!!
不信你可以試試,直接用 Object
類接收一個基本資料型別 int
,完全是可以的。
Object obj = 10; int temp = (Integer) obj;
解釋一下上面這段程式碼發生了什麼,下面這張圖很重要,大家仔細看:
其實包裝類最常見的使用就是在集合中,因為集合不允許儲存基本型別的資料,只能儲存參照型別的資料。那如果我們想要儲存 1、2、3 這樣的基本型別資料怎麼辦?舉個例子,我們可以如下宣告一個 Integer
物件的陣列列表:
ArrayList<Integer> list = new ArrayList<>();
往這個列表中新增 int
型資料:
list.add(3);
上面這個呼叫在底層將會發生自動裝箱操作:
list.add (Integer.valueOf(3));
基本資料型別 int
會被轉換成 Integer
物件存入集合中。
我們再來從這個集合中根據某個下標 i 獲取對應的 Integer
物件,並用基本資料型別 int
接收:
int n = list.get(i);
上面這個呼叫在底層將會發生自動拆箱操作:
int n = list.get(i).intValue();
另外,除了在集合中的廣泛應用,包裝類還包含一個重要功能,那就是提供將String型資料變為基本資料型別的方法,使用幾個代表的類做說明:
Integer
:
Double
:
Boolean
:
這些方法均被 static
標識,也就是說它們被各自對應的所有物件共同維護,直接通過類名存取該方法。舉個例子:
String str = "10"; int temp = Integer.parseInt(str);// String -> int System.out.println(temp * 2); // 20
需要特別注意的是:Character
類裡面並不存在字串變為字元的方法,因為 String
類中已經有一個 charAt()
的方法可以根據索引取出字元內容。
以上就是淺析Java中為什麼要設計包裝類的詳細內容,更多關於Java 設計包裝類的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45