為何要包裝類
? ? 1. 在面向?qū)ο笾?”一切皆對(duì)象”,但基本數(shù)據(jù)類型的特殊存在不太符合這一理念确封,面向?qū)ο竺嫦虻貌⒉患兇獬牵驗(yàn)榛绢愋妥兞坎⒉皇菍?duì)象再菊;
? ? 2. 涉及進(jìn)制間的轉(zhuǎn)換的算法,數(shù)據(jù)類型間的基本操作颜曾;如果都要我們來實(shí)現(xiàn)纠拔,那工作量就太大了;
? ? 3. Java的集合框架并不支持基本數(shù)據(jù)類型的存儲(chǔ)泛豪,只支持對(duì)象類型的存儲(chǔ)稠诲,支持基本類型存儲(chǔ)的就只有數(shù)組了;
故此诡曙,針對(duì)Java基本數(shù)據(jù)類型封裝了包裝類臀叙,每一個(gè)基本類型都有一個(gè)對(duì)應(yīng)的包裝類,以下是詳情:
八大基本數(shù)據(jù)類型的包裝類都使用final修飾价卤,都是最終類劝萤,都不能被繼承。
拆箱和裝箱
裝箱:把基本類型數(shù)據(jù)轉(zhuǎn)成對(duì)應(yīng)的包裝類對(duì)象慎璧。
方式一:Integer i = Integer.value(13)床嫌;
方式二:Integer i = new Integer(13);
拆箱:把包裝類對(duì)象轉(zhuǎn)成對(duì)應(yīng)的基本數(shù)據(jù)類型數(shù)據(jù)。
int value = i.intValue();
自動(dòng)裝箱(Autoboxing)和自動(dòng)拆箱(AutoUnboxing)
在Java 5之前的版本中胸私,基本數(shù)據(jù)類型和包裝類之間的轉(zhuǎn)換是需要手動(dòng)進(jìn)行的,但Sun公司從Java5開始提供了的自動(dòng)裝箱(Autoboxing)和自動(dòng)拆箱(AutoUnboxing)操作 厌处;
自動(dòng)裝箱:可以把一個(gè)基本類型變量直接賦給對(duì)應(yīng)的包裝類型變量。比如:Integer i = 13;
自動(dòng)拆箱:允許把包裝類對(duì)象直接賦給對(duì)應(yīng)的基本數(shù)據(jù)類型變量岁疼。
比如:Integer i = new Integer(13);
? ? ? ? ? ?Int j = i;
自動(dòng)裝箱和自動(dòng)拆箱嘱蛋,也是一個(gè)語(yǔ)法糖/編譯器級(jí)別新特性,在底層依然是手動(dòng)裝箱五续、拆箱操作洒敏;但是在裝箱操作中使用的是Integer.valueOf()方法,而不是直接new Integer();其他的幾個(gè)包裝類也是如此疙驾,裝箱操作中使用的是各自的valueOf()方法凶伙。
switch 對(duì)包裝類的支持
switch支持的基本數(shù)據(jù)類型:byte,short,char,int;也支持對(duì)應(yīng)的包裝類它碎。因?yàn)樵诘讓雍伲瑂witch中會(huì)對(duì)包裝類做手動(dòng)拆箱操作。
考慮后面這樣一句代碼:Object obj = 17;
在上述代碼語(yǔ)句中有如下的操作:
1. 自動(dòng)裝箱扳肛,把17自動(dòng)裝箱為Integer類型: Integer i = 17;
2. 引用的自動(dòng)類型轉(zhuǎn)換傻挂,把子類對(duì)象賦給父類變量: Object obj = i; 因?yàn)镺bject類是所有Java類的父類;因此挖息,Object類型可以接受一切數(shù)據(jù)類型的值金拒;Object數(shù)組:Object[],該數(shù)組可以保存一切數(shù)據(jù)類型。所以:Object[] arr = {“A”,12,3.14,true}; // 這是完全可行的
包裝類的常用操作方法(以Integer為例)
1. 包裝類中的常量:
? ? ?MAX_VALUE :最大值
? ? ?MIN_VALUE :最小值
? ? ?SIZE :變量在內(nèi)存中存儲(chǔ)數(shù)據(jù)占多少位
? ? ?TYPE :對(duì)應(yīng)的基本類型
2. 包裝類的構(gòu)造器:創(chuàng)建包裝類對(duì)象
案例代碼如下所示:
其他的幾個(gè)包裝類型也是這樣的規(guī)律绪抛,具體實(shí)現(xiàn)查看源碼即可资铡。
3. 基本類型和包裝類型的轉(zhuǎn)換(裝箱和拆箱)
裝箱:
拆箱:
4. String和基本類型/包裝類型之間的轉(zhuǎn)換操作
把String轉(zhuǎn)換為包裝類類型
把包裝類對(duì)象轉(zhuǎn)換為String
把基本數(shù)據(jù)類型轉(zhuǎn)換為String
把String轉(zhuǎn)換為基本數(shù)據(jù)類型
parseXxx(String s) : xxx表示8大基本數(shù)據(jù)類型,如:
5. 對(duì)于Boolean來說
無(wú)論是使用new Boolean(“”); 還是Boolean.valueOf(“”), 只有使用true/TRUE會(huì)被認(rèn)為是true幢码,其他都是false笤休。
包裝類中的緩存設(shè)計(jì)
在包裝類中提供了緩存設(shè)計(jì),會(huì)對(duì)一定范圍內(nèi)的數(shù)據(jù)作緩存症副,如果數(shù)據(jù)在范圍內(nèi)店雅,會(huì)優(yōu)先從緩存中取數(shù)據(jù),超出范圍才會(huì)創(chuàng)建新對(duì)象贞铣;Byte底洗、Short、Integer咕娄、Long:緩存[-128亥揖,127]區(qū)間的數(shù)據(jù);Character:緩存[0圣勒,127]區(qū)間的數(shù)據(jù)费变;包裝類中的緩存設(shè)計(jì),也稱為享元模式圣贸。
緩存設(shè)計(jì)會(huì)在包裝類中的valueOf()方法中實(shí)現(xiàn)挚歧,所以才會(huì)推薦使用valueOf()方法來實(shí)現(xiàn)拆箱操作,如下是Integer類的valueOf()源碼:
再查看緩存實(shí)現(xiàn)細(xì)節(jié):
通過查看源碼可知吁峻,JVM會(huì)對(duì)-128 到 127之間的做緩存滑负,如果你的變量值在這個(gè)范圍內(nèi),就會(huì)優(yōu)先從緩存中取數(shù)據(jù)用含,否則就會(huì)創(chuàng)建新對(duì)象矮慕。當(dāng)然這個(gè)緩存區(qū)間也是可是設(shè)置的。
那么以下這個(gè)例子就可以解釋了:
我們?cè)賮砜碔nteger的equals方法的實(shí)現(xiàn)源碼:
可以發(fā)現(xiàn)啄骇,包裝類在比較時(shí)會(huì)將包裝類型拆箱為基本數(shù)據(jù)類型痴鳄,并使用==做比較。
包裝類型和基本數(shù)據(jù)類型的區(qū)別
包裝類型和基本數(shù)據(jù)類型的區(qū)別(以Integer與int的區(qū)別為例):
1.默認(rèn)值:
????????int(基本數(shù)據(jù)類型呢)的默認(rèn)值是0缸夹。
????????Integer(包裝類型)的默認(rèn)值為null痪寻。Integer既可以表示null,又可以表示0虽惭。
2.包裝類中提供了該類型相關(guān)的很多算法操作方法:
3.在集合框架中,只能存儲(chǔ)對(duì)象類型,不能存儲(chǔ)基本數(shù)據(jù)類型值橡类。
4.Integer和int并不是相同的數(shù)據(jù)類型,盡管值是相同的芽唇。Integer是一個(gè)類顾画,可以實(shí)例化為對(duì)象,但int只是一個(gè)基本數(shù)據(jù)類型。
5.在JVM中亲雪,基本類型變量存儲(chǔ)在棧中的,而包裝類型對(duì)象存放于堆中疚膊。
其實(shí)义辕,包裝類就是把基本數(shù)據(jù)類對(duì)象化,包裝類是基本數(shù)據(jù)類型的超集寓盗;在開發(fā)中灌砖,建議成員變量?jī)?yōu)先使用包裝類型,局部變量?jī)?yōu)先考慮基本數(shù)據(jù)類型傀蚌。
完結(jié)基显。老夫雖不正經(jīng),但老夫一身的才華