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