閱讀本文大概需要6分鐘。
007:如何理解Java中的包裝類?
Java的型別系統由兩部分組成:基本型別(primitive)和取用型別(reference type)。包裝類指的是Java基礎型別對應的取用型別。每個基本型別都有一個對應的包裝類:
-
boolean、byte、short、char、int、long、float、double
-
Boolean、Byte、Short、Character、Integer、Long、Float、Double
基本型別和包裝型別有三個區別:
-
基本型別只有值,而包裝型別則是一個物件,也就是說,兩個包裝型別的物件,它們的值相同,但是物件地址可以不同;
-
包裝型別除了擁有基本型別的功能外,還可以表示null的概念;
-
基本型別通常比包裝型別更省時間和空間。
008:為什麼Java需要包裝類這個概念?
在Java中的泛型類不支援基本型別,只支援取用型別,因此,如果我們希望在泛型類中使用基本型別,就需要將基本型別先轉換成取用型別。例如:Java集合框架只能存放取用型別的元素。
009:建立包裝類實體的方式有哪些?
將基本型別轉換成取用型別的方式有兩種:構造方法、靜態工廠方法。這裡看一個將int值轉換成Integer物件的例子,程式碼如下:
Integer object = new Integer(1);
Integer anotherObject = Integer.valueOf(1);
這兩種轉換方式對於int轉Integer有區別:valueOf方法會優先傳回快取的資料([-128,127]),如果超出這個範圍,才會使用構造方法建立包裝型別。valueOf的程式碼如下:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
另外,如果需要從一個包裝型別轉換成基本型別,則需要使用相關的方法,例如:intValue()、doubleValue()等等:
int val = object.intValue();
010:如何理解自動裝箱?
在Java 1.5之前,開發者必須手動處理包裝型別和基本型別之間的轉換,例如要在一個集合中放入整數的時候,直接呼叫coll.add(5)
是不支援的。
Java 1.5增加了自動裝箱(autoboxing)和自動拆箱(auto-unboxing)的特性,可自動完成包裝型別和基本型別的轉換。自動裝箱指的是自動將一個基本型別轉換成包裝型別物件。
什麼時候會發生自動裝箱呢?
-
在執行方法呼叫時,傳遞一個基本型別的值給到一個方法引數為包裝型別的方法中
-
將一個基本型別的值賦值給一個包裝型別物件。
上述兩種情況的例子程式碼如下:
List<Integer> list = new ArrayList<>();
list.add(1); //自動裝箱
Integer val = 2; //自動裝箱
011:自動裝箱有什麼好處?
自動裝箱有助於提高程式碼的可讀性。
不過在一些情況下,卻不推薦自動裝箱特性,例如:在迴圈中,下麵的程式碼比預計的執行起來要慢一點:
public static void main(String[] args) {
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i; //sum被不斷得自動拆箱和裝箱
}
System.out.printfln(sum);
}
012:如何理解型別轉換?
型別的轉換是在等號左邊和等號右邊的變數資料型別不一致的時候發生,這時候需要將一個數字從一個資料型別轉換成另一種資料型別。資料型別的轉換可以分為隱式轉換(自動型別轉換)和顯式轉換(強制型別轉換)兩種。
013:如何理解隱式轉換?
隱式轉換需要滿足兩個條件:
-
兩種資料型別相容
-
標的型別的取值範圍大於源資料型別(低階型別資料轉換成高階型別資料)。例如:byte型別的資料賦值給short型別的變數時,由於short型別的取值範圍比較大,這裡會發生隱式轉換
資料型別的級別規定如下(從左到右的轉換順序):
-
數值型別的資料轉換:byte——>short——>int——>long——>float——>double
-
字元型別轉換為整數:char——>int
014:如何理解顯式轉換?
當兩種型別的資料不相容時,或者標的型別的取值範圍小於源型別時,就無法進行隱式轉換,這時候就需要進行顯式轉換(強制型別轉換),例子程式碼如下:
int a = 3;
double b = 5.5;
a = (int)b;//顯式轉換,會丟精度
參考資料
-
https://www.baeldung.com/java-wrapper-classes
-
《Effective Java》
-
http://c.biancheng.net/view/796.html
-
https://www.baeldung.com/java-type-casting
-
https://www.baeldung.com/java-primitive-conversions