基礎鞏固、探尋Java裝箱和拆箱的奧妙!

不一樣的科技宅發表於2023-05-01

前言

  今天在逛某知名論壇的時候,看到一篇"請不要使用包裝型別,避免造成效能損失"的文章。一下子就吸引了我的注意。大意就是,能用基本資料型別就儘量用基本資料型別,因為包裝型別自動拆箱、裝箱會帶來效能損失尤其是迴圈使用時會大量建立物件。所以今天聊一下,Java的裝箱和拆箱。

什麼是裝箱和拆箱?

  Java中的裝箱(boxing)和拆箱(unboxing)是指將基本資料型別與其對應的包裝類之間進行轉換的過程。

裝箱

  裝箱是將基本資料型別轉換為其對應的包裝類,例如將int型別轉換為Integer型別。這個過程是透過自動裝箱(autoboxing)或手動裝箱(manual boxing)完成的。自動裝箱是指Java編譯器自動將基本型別轉換為包裝型別,而手動裝箱則是透過呼叫包裝類的建構函式來完成。

拆箱

  拆箱是將包裝類轉換為其對應的基本資料型別,例如將Integer型別轉換為int型別。這個過程也是透過自動拆箱(autounboxing)或手動拆箱(manual unboxing)完成的。自動拆箱是指Java編譯器自動將包裝型別轉換為基本型別,而手動拆箱則是透過呼叫包裝類的xxxValue()方法來完成。

為啥要包裝型別?

  在日常使用的時候,感覺用基本型別還是包裝型別貌似沒啥區別。如果去掉包裝型別,那就不需要裝箱和拆箱了。也就避免了效能損失。貌似很完美呀。

  如果你是這樣想就,大錯特錯了。java中有基本資料型別和包裝型別,這是為了滿足不同需求的設計。java大佬們肯定不會做這樣的無用功的,使用包裝型別的主要原因包括:

  • 物件引用:基本型別不是物件,無法使用物件引用,而包裝型別是物件,可以透過引用來操作。
  • 泛型:泛型不能使用基本資料型別,必須使用包裝型別。如,使用List<Integer>來儲存一組整數,而不是使用List<int>
  • null值:基本型別不能為null,而包裝型別可以為null。
  • 型別轉換:包裝型別提供了許多型別轉換方法,例如將字串轉換為整數或浮點數等,這些方法非常方便。
  • 方法過載:方法過載可以使用不同的引數型別,但是基本資料型別和其對應的包裝型別在方法中被認為是相同的型別,因此可以在方法中使用它們進行過載。

  儘管基本資料型別在Java中非常有用,但是包裝型別提供了更多的功能和靈活性,因此在某些情況下使用包裝型別會更為方便和實用。所以就有了裝箱和拆箱的過程。

裝箱和拆箱的進化過程

  在Java 1.4及之前,裝箱和拆箱需要手動進行,即需要使用對應的建構函式或方法來完成。例如,要將int型別的變數x裝箱成Integer型別,可以使用以下程式碼:

int x = 10;
Integer y = new Integer(x);  // 手動裝箱

要將Integer型別的變數y拆箱成int型別,可以使用以下程式碼:

Integer y = new Integer(10);
int x = y.intValue();  // 手動拆箱

  這種方式比較繁瑣,也容易出錯。因此,從Java 5開始,引入了自動裝箱和拆箱機制。這意味著我們可以直接將基本資料型別賦值給對應的封裝型別變數,或將封裝型別變數賦值給對應的基本資料型別變數,編譯器會自動完成轉換。例如:

int x = 10;
Integer y = x;  // 自動裝箱
int z = y;  // 自動拆箱

  從Java 9開始,引入了一種新的裝箱方式,稱為“緊湊型裝箱”(Compact Number Box),它能夠更高效地儲存小範圍內的數值。緊湊型裝箱只適用於byte、short和int型別的封裝型別,這些型別的取值範圍都比較小(如byte的取值範圍為-128到127),因此可以使用一個byte或short型別的變數來儲存它們的值,而無需使用一個整型變數。

到底該如何選擇呢?

  基本型別是Java語言的基礎,可以直接儲存在棧中,具有較高的執行效率和較小的記憶體佔用。包裝型別是把基本型別封裝起來的物件,可以在堆中儲存,可以進行各種物件導向的操作。所以在選擇使用基本型別還是包裝型別時,可以考慮以下幾個因素:

  1. 執行效率:基本型別具有較高的執行效率,尤其是在大量計算的情況下,使用基本型別可以明顯提高程式的執行速度。
  2. 記憶體佔用:基本型別在棧中儲存,佔用的記憶體較小,而包裝型別在堆中儲存,佔用的記憶體較大。
  3. 物件操作:如果需要進行物件導向的操作,例如透過equals()方法比較兩個變數的值,或者將基本型別轉換為字串,就需要使用包裝型別。
  4. 空值處理:基本型別不能表示空值,而包裝型別可以用null表示空值,因此在需要處理空值的情況下,需要使用包裝型別。

總結

  Java中的裝箱和拆箱技術經歷了從手動到自動、從普通到緊湊型的演進,這使得我們能夠更方便地操作基本資料型別和封裝型別之間的轉換。雖然更加方便, 但是在實際開發中,還是需要根據具體的使用場景進行選擇。

結尾

  如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的主頁看看,說不定有你喜歡的文章,也可以隨手點個關注哦,謝謝。

  我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活。我們下期見!

相關文章