Java中八大包裝類舉例詳解(通俗易懂)
一、包裝類(Wrapper Class)
1、簡要介紹
Java 中的包裝類是用于將基本數(shù)據(jù)類型(如 int、char、boolean 等)包裝成對象的類。每種基本數(shù)據(jù)類型都有對應的包裝類,這些包裝類提供了一種面向?qū)ο蟮姆绞絹硖幚砘緮?shù)據(jù)類型,允許它們被用于需要對象的場景,如集合框架、泛型等。
以下是 Java 中基本數(shù)據(jù)類型及其對應的包裝類:
基本數(shù)據(jù)類型 | 對應的包裝類 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
2、包裝類特點
封裝性:所有的包裝類都是 final 類,這意味著它們不能被繼承。這種設計確保了包裝類的行為和特性的一致性,從而避免了子類可能引入的不確定性。
不可變性:包裝類的實例一旦被創(chuàng)建后,其中保存的基本數(shù)據(jù)類型數(shù)據(jù)就不能再被改變。這種不可變性使得包裝類在多線程環(huán)境中更加安全,避免了因數(shù)據(jù)被意外修改而導致的錯誤。
提供方法:包裝類封裝了許多實用的方法,提供了豐富的功能。例如,它們支持數(shù)據(jù)類型轉換、判斷字符串的大小寫、以及獲取最大值和最小值等。
繼承關系:除了 Character 和 Boolean 之外,其他所有的包裝類都繼承自 Number 類。這種繼承關系使得這些包裝類能夠共享一些通用的功能和特性,例如數(shù)字的比較和轉換,這為在不同數(shù)值類型之間的操作提供了一致的接口。
3、包裝類用途
對象操作:在Java中,許多集合類和框架方法需要對象作為參數(shù),而不是基本數(shù)據(jù)類型。為了滿足這一需求,包裝類提供了將基本數(shù)據(jù)類型轉換為對象的機制。通過使用包裝類,我們可以輕松地在這些方法中傳遞基本數(shù)據(jù)類型。
Null值處理:基本數(shù)據(jù)類型無法為
null
,而包裝類則可以。這一特性在某些情況下非常有用,例如在方法參數(shù)中,需要表示可選值或缺省值時。通過使用包裝類,我們能夠更靈活地處理這些場景,確保代碼的健壯性和可讀性。這種設計使得我們在處理數(shù)據(jù)時,可以更方便地進行null
值檢查,并在需要時安全地進行區(qū)分,從而提高了代碼的靈活性。
二、裝箱和拆箱
1、裝箱和拆箱
裝箱(Boxing)是將基本數(shù)據(jù)類型轉換為相應的包裝類的過程。拆箱(Unboxing)是將包裝類轉換為基本數(shù)據(jù)類型的過程。
手動裝箱就是使用一個值創(chuàng)建一個 Integer 對象:
int num = 50000; Integer boxedInt1 = new Integer(num); // 手動裝箱方式一 Integer boxedInt2 = Integer.valueOf(num); // 手動裝箱方式二
手動拆箱就是使用 Integer 類型對象的 intValue() 方法來獲取這個對象的 int 值:
Integer boxedInt = new Integer(5); int num = boxedInt.intValue(); // 手動拆箱
2、自動裝箱和自動拆箱
Java 5引入了自動裝箱(Auto-boxing)和自動拆箱(Auto-unboxing)機制,簡化了基本數(shù)據(jù)類型與包裝類之間的轉換過程。
自動裝箱是將基本數(shù)據(jù)類型自動轉換為其對應的包裝類對象的過程。
int num = 50000; Integer boxedInt = num; // 自動裝箱
自動拆箱則是將包裝類對象自動轉換為其對應的基本數(shù)據(jù)類型。
Integer boxedInt = new Integer(50000); int num = boxedInt; // 自動拆箱
3、自動裝箱和自動拆箱的底層實現(xiàn)
1)自動裝箱的底層實現(xiàn)
自動裝箱是通過調(diào)用包裝類的valueOf()方法來實現(xiàn)的。
我們可以通過調(diào)試來驗證這一結論,在要發(fā)生自動裝箱的地方打上斷點,然后直接跳到這個斷點處,然后強制進入(force step into),就會進入到 valueOf() 方法中。
2)自動拆箱的底層實現(xiàn)
自動拆箱是通過調(diào)用包裝類對象的xxxValue()方法來實現(xiàn)的。
我們可以通過調(diào)試來驗證這一結論,在要發(fā)生自動拆箱的地方打上斷點,然后直接跳到這個斷點處,然后強制進入(force step into),就會進入到 xxxValue() 方法中。
三、包裝類的緩存機制
1、簡要介紹
Java中的包裝類緩存機制是為了優(yōu)化性能和節(jié)省內(nèi)存而設計的。
它為整型(Byte、Short、Integer、Long)、字符型(Character)和布爾型(Boolean)的包裝類提供了緩存,確保在這些類型的小范圍值之間可以復用對象。而對于浮點數(shù)類型的包裝類(Float、Double),則沒有這種緩存機制,意味著每次都需要創(chuàng)建新的對象。
這樣一來,Java在處理常用值時更加高效,但在浮點數(shù)處理上則相對簡單直接。
2、緩存范圍
對于 Integer 類,Java會緩存范圍在 -128 到 127 之間的所有整數(shù)。
對于 Byte、Short 和 Character 類,緩存的范圍也是類似的。具體范圍如下:
- Byte:-128 到 127
- Short:-128 到 127
- Character:0 到 127(即所有的ASCII字符)
- Boolean:只有 true 和 false 兩個值會被緩存。
3、觸發(fā)緩存機制
只有調(diào)用 valueOf() 方法時,如果要創(chuàng)建的值已經(jīng)被緩存,則會觸發(fā)緩存機制。
我們可以查看 Integer 類的 valueOf() 方法的源代碼:
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
如果要創(chuàng)建的 Integer 對象的值在預定范圍內(nèi),則返回緩存的對象,如果不在范圍內(nèi),則直接新創(chuàng)建一個對象。
4、測試緩存機制
我們可以通過使用 valueOf() 方法創(chuàng)建兩個值一樣且值在范圍內(nèi)的對象,然后比較它們的引用是否相等,如果相等,則能證明緩存機制的存在。
public class Example { public static void main(String[] args) { Integer i1 = Integer.valueOf(1); Integer i2 = Integer.valueOf(1); System.out.println(i1 == i2); } }
運行結果:
這樣就能證明緩存機制的存在。
四、包裝類的方法
1、基本轉換方法
parseInt(String s), parseDouble(String s), parseBoolean(String s) 等:將字符串轉換為相應的基本類型。
valueOf(String s): 返回對應類型的包裝類實例,例如 Integer.valueOf("123") 返回一個 Integer 對象。
2、獲取基本類型值
intValue(), doubleValue(), charValue(), booleanValue() 等: 返回包裝類中封裝的基本類型值。
示例:
Integer num = new Integer(5); int value = num.intValue();
3、常量字段
MAX_VALUE, MIN_VALUE: 返回該包裝類所表示的基本類型的最大值和最小值。
例如:
Integer.MAX_VALUE 返回 2147483647,
Double.MIN_VALUE 返回 4.9E-324。
4、比較方法
compareTo(T another): 用于比較兩個包裝類對象的大小。
equals(Object obj): 判斷兩個對象是否相等。
示例:
Integer.compare(x, y) 方法比較兩個 Integer 對象的值。
5、類型檢測
isNaN(), isInfinite(): 用于 Double 和 Float 以檢測是否為非數(shù)字或無窮大。
isLetter(char ch):檢查指定的字符是否為字母(包括大寫和小寫字母)。
char c = 'A'; boolean isLetter = Character.isLetter(c); // 返回 true
isDigit(char ch):檢查指定的字符是否為數(shù)字。
char c = '5'; boolean isDigit = Character.isDigit(c); // 返回 true
isWhitespace(char ch):檢查指定的字符是否為白空格字符(如空格、制表符等)。
char c = ' '; boolean isWhitespace = Character.isWhitespace(c); // 返回 true
五、補充
1、精度提升
public class Example { public static void main(String[] args) { Object obj = true ? new Integer(1) : new Double(2.0); System.out.println(obj); } }
輸出結果是:
這是因為由于 Double 精度高,而且這里使用的是三元運算符,所以 Integer 會被提升精度為 Double,所以最終輸出的是一個浮點數(shù)。
實際上的具體操作應該是:
創(chuàng)建一個 Integer 對象,然后這個對象自動拆箱得到一個 int 類型的值,然后由于后面是 Double 類型,這個 int 類型的值提升為 double 類型的值,然后通過自動裝箱得到一個 Double 類型的對象。
我們也可以通過 instanceof 操作符測試一下:
public class Example { public static void main(String[] args) { Object obj = true ? new Integer(1) : new Double(2.0); System.out.println(obj instanceof Double); } }
輸出結果:
所以說這里的 obj 指向的對象確實是一個 Double 類的對象。
2、包裝類與字符串相互轉換
1)包裝類轉換為字符串
Integer i = 10000; // 方式一 String str1 = i + ""; // 方式二 String str2 = i.toString(); // 方式三 String str3 = String.valueOf(i);
這里對于方法三,實際上內(nèi)部也是調(diào)用 toString() 方法的。
2)字符串轉換為包裝類
String str = "10000"; // 方式一 Integer i1 = Integer.parseInt(str); // 方式二 Integer i2 = Integer.valueOf(str); // 方式三 Integer i3 = new Integer(str);
這里看似通過字符串創(chuàng)建 Integer 類對象有三種方法,實際上就一種方法,對于方法二和方法三內(nèi)部實際上都是調(diào)用 parseInt() 方法來將字符串轉換為整型的。
3、緩存機制
上面提到的緩存機制只可能在調(diào)用 valueOf() 方法時觸發(fā),所以對于直接調(diào)用構造方法則不會觸發(fā)緩存機制。
我們知道自動裝箱底層調(diào)用的也是 valueOf() 方法,所以說自動裝箱也可以觸發(fā)緩存機制。
我們還知道緩存機制是有范圍的,超出范圍的值創(chuàng)建的對象都是新創(chuàng)建的。
所以我們就能很自然的得到以下代碼的運行結果:
public class Example { public static void main(String[] args) { Integer i1 = new Integer(1); Integer i2 = new Integer(1); System.out.println(i1 == i2); // false Integer i3 = 1; Integer i4 = 1; System.out.println(i3 == i4); // true Integer i5 = 128; Integer i6 = 128; System.out.println(i5 == i6); // false } }
運行結果:
4、判斷值是否相等
只要判斷中有基本數(shù)據(jù)類型,則判斷的就是值是否相等,也就是說包裝類在這時會自動拆箱。
public class Example { public static void main(String[] args) { Integer i1 = 128; int i2 = 128; System.out.println(i1 == i2); } }
運行結果:
總結
到此這篇關于Java中八大包裝類的文章就介紹到這了,更多相關Java八大包裝類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中StringBuilder字符串類型的操作方法及API整理
Java中的StringBuffer類繼承于AbstractStringBuilder,用來創(chuàng)建非線程安全的字符串類型對象,下面即是對Java中StringBuilder字符串類型的操作方法及API整理2016-05-05Spring Cloud下OAUTH2注銷的實現(xiàn)示例
本篇文章主要介紹了Spring Cloud下OAUTH2注銷的實現(xiàn)示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03Java高性能本地緩存框架Caffeine的實現(xiàn)
本文主要介紹了Java高性能本地緩存框架Caffeine的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解
這篇文章主要介紹了JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解,CountDownLatch 類可以設置一個計數(shù)器,然后通過 countDown 方法來進行 減 1 的操作,使用 await 方法等待計數(shù)器不大于 0,然后繼續(xù)執(zhí)行 await 方法 之后的語句,需要的朋友可以參考下2024-01-01Springboot如何使用mybatis實現(xiàn)攔截SQL分頁
這篇文章主要介紹了Springboot使用mybatis實現(xiàn)攔截SQL分頁,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06