Wrapper包裝類和拆箱裝箱

Wrapper包裝類

我們知道Java是一個面相對象的編程語言错沃,基本類型并不具有對象的性質(zhì),為了讓基本類型也具有對象的特征屿岂,就出現(xiàn)了包裝類型(如我們在使用集合類型Collection時就一定要使用包裝類型而非基本類型)携狭,它相當(dāng)于將基本類型“包裝起來”旧找,使得它具有了對象的性質(zhì),并且為其添加了屬性和方法吹艇,豐富了基本類型的操作惰蜜。
另外,當(dāng)需要往ArrayList受神,HashMap中放東西時抛猖,像int,double這種基本類型是放不進(jìn)去的,因為容器都是裝object的财著,這是就需要這些基本類型的包裝器類了联四。

下面看一下基本數(shù)據(jù)類型和包裝類的對應(yīng):
image.png
拆箱和裝箱

先看一段代碼:

  public static void main(String args[]){
        int a = 200;
        //普通封裝包裝類型
        Integer A1 = new Integer(a);
        // 自動裝箱
        Integer A2 = a;

        Integer B = new Integer(200);
        //普通拆箱
        int b1 = Integer.valueOf(B);
        //自動拆箱
        int b2 = B;
}
基本類型和包裝類型的區(qū)別

①基本類型不使用new關(guān)鍵字,他是個常量瓢宦。而包裝類型需要使用new關(guān)鍵字來在堆中分配存儲空間碎连,是個對象;
②基本類型是直接將變量值存儲在棧中(常量在棧中)驮履,而包裝類型是將對象放在堆中(對象在堆中)鱼辙,然后通過引用來使用;
③基本類型的初始值如int為0玫镐,boolean為false倒戏,而包裝類型的初始值為null;
④基本類型使用比較廣泛恐似,包裝類型一般用在ArrayList杜跷,HashMap中。

面試中的常見坑

1.這段代碼的輸出

    public static void main(String args[]){

        int a1 = 300;
        int a2 = 300;

        Integer A1 = new Integer(300);
        Integer A2 = new Integer(300);

        Integer C1 = 3;
        Integer D1 = 3;

        Integer C2 = 300;
        Integer D2 = 300;

        System.out.println(a1 == a2);//true
        System.out.println(A1 == A2);//false
        System.out.println(C1 == D1);//true
        System.out.println(C2 == D2);//false
        System.out.println(a1 == A1);//true
        System.out.println(A1 == C2);//false
        System.out.println(a1 == C2);//true
    }

下面我們逐一分析結(jié)果
①System.out.println(a1 == a2);//true

因為都是int型矫夷,是基本數(shù)據(jù)類型葛闷,所以==在比較基本數(shù)據(jù)類型的時候,只比較數(shù)值双藕。

②System.out.println(A1 == A2);//false
因為A1淑趾,A2都是new的對象,所以都是在堆中開辟了新的空間的忧陪,==在比較對象的時候扣泊,比較的是引用中存儲的地址,所以是false嘶摊。
③System.out.println(C1 == D1);//true
System.out.println(C2 == D2);//false

這兩個合起來看延蟹,這是咋地啦?怎么換個數(shù)結(jié)果就不一樣了叶堆?

下面這段代碼是Integer的valueOf方法的具體實現(xiàn):

public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

而其中IntegerCache類的實現(xiàn)為:

private static class IntegerCache {
        static final int high;
        static final Integer cache[];

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

從上面2段代碼可以看出阱飘,在通過valueOf方法創(chuàng)建Integer對象的時候,如果數(shù)值在[-128,127]之間蹂空,便返回指向IntegerCache.cache中已經(jīng)存在的對象的引用俯萌;否則創(chuàng)建一個新的Integer對象。

④ System.out.println(a1 == A1);//true
System.out.println(A1 == C2);//false
System.out.println(a1 == C2);//true
先分別說一下a1是基本數(shù)據(jù)類型上枕,A1是普通的裝箱的對象咐熙,C2是自動裝箱的對象。
a1==A1:是基本數(shù)據(jù)類型==普通封裝的對象辨萍,這個時候包裝類對象會自動拆箱棋恼,然后比較數(shù)值返弹。
A1 == C2: 自動裝箱也是new了個對象,所以他倆內(nèi)存中地址是不一樣的爪飘。
a1 == C2:和a1==A1同理义起。
2.下面代碼的結(jié)果

    public static void main(String args[]){
        double a1 = 100.0;
        double a2 = 100.0;

        Double B1 = 100.0;
        Double B2 = 100.0;

        Double C1 = 200.0;
        Double C2 = 200.0;

        System.out.println(a1 == a2);//true
        System.out.println(a1 == B1);//true
        System.out.println(B1 == B2);//false
        System.out.println(C1 == C2);//false
    }

①前面兩個
System.out.println(a1 == a2);//true
System.out.println(a1 == B1);//true

老生常談了哈,就是基本數(shù)據(jù)類型之間==比較值师崎,封裝類型和基本數(shù)據(jù)類型==時默终,封裝類型自動拆箱了,所以都是true犁罩!

②后面兩個
System.out.println(B1 == B2);//false
System.out.println(C1 == C2);//false
怎么和int不一樣了齐蔽,沒有緩存了嗎?是的床估,沒有含滴!

    public static Double valueOf(double d) {
        return new Double(d);
    }

源碼里直接,給new了個對象丐巫,這個糟老頭子壞得很谈况!23333
注意:
Integer、Short递胧、Byte碑韵、Character、Long這幾個類的valueOf方法的實現(xiàn)是類似的缎脾。
Double泼诱、Float的valueOf方法的實現(xiàn)是類似的。

3.下面這段代碼的結(jié)果

   public static void main(String[] args) {
         
        Boolean a1 = false;
        Boolean a2 = false;
        Boolean b1 = true;
        Boolean b2 = true;
         
        System.out.println(a1==a2);//true
        System.out.println(b1==b2);//true
    }

為啥都是true呢赊锚,因為源碼中true和false都被定義了靜態(tài)屬性。

public static final Boolean TRUE = new Boolean(true);

    /** 
     * The <code>Boolean</code> object corresponding to the primitive 
     * value <code>false</code>. 
     */
    public static final Boolean FALSE = new Boolean(false);

4.下面代碼的輸出

    public static void main(String args[]){
        Integer a = 10;
        Integer b = 20;
        Integer c = 30;
        Integer d = 30;
        Long g = 30L;
        Long h = 20L;

        System.out.println(c==(a+b));//true
        System.out.println(c.equals(a+b));//true
        System.out.println(g==(a+b));//true
        System.out.println(g.equals(a+b));//false
        System.out.println(g.equals(a+h));//true
    }

在分析上面代碼結(jié)果前屉栓,要明白四件事:
①當(dāng) "=="運(yùn)算符的兩個操作數(shù)都是 包裝器類型的引用舷蒲,則是比較指向的是否是同一個對象,就是要看引用友多;
②當(dāng) "=="運(yùn)算符的兩個操作數(shù)其中有一個操作數(shù)是表達(dá)式(即包含算術(shù)運(yùn)算)則比較的是數(shù)值(即會觸發(fā)自動拆箱的過程)牲平。
③對于包裝器類型,equals方法并不會進(jìn)行類型轉(zhuǎn)換域滥。euqals會先比較數(shù)據(jù)類型纵柿,再比較值!
④兩個不同的數(shù)據(jù)類型相加启绰,結(jié)果是高的那個數(shù)據(jù)類型昂儒,比如int+float,返回的是float委可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渊跋,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拾酝,老刑警劉巖燕少,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蒿囤,居然都是意外死亡客们,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門材诽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來底挫,“玉大人,你說我怎么就攤上這事岳守∑喔遥” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵湿痢,是天一觀的道長涝缝。 經(jīng)常有香客問我,道長譬重,這世上最難降的妖魔是什么拒逮? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮臀规,結(jié)果婚禮上滩援,老公的妹妹穿的比我還像新娘。我一直安慰自己塔嬉,他們只是感情好玩徊,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谨究,像睡著了一般恩袱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胶哲,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天畔塔,我揣著相機(jī)與錄音,去河邊找鬼鸯屿。 笑死澈吨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寄摆。 我是一名探鬼主播谅辣,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼婶恼!你這毒婦竟也來了屈藐?” 一聲冷哼從身側(cè)響起榔组,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎联逻,沒想到半個月后搓扯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡包归,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年锨推,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片公壤。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡换可,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厦幅,到底是詐尸還是另有隱情沾鳄,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布确憨,位于F島的核電站译荞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏休弃。R本人自食惡果不足惜吞歼,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望塔猾。 院中可真熱鬧篙骡,春花似錦、人聲如沸丈甸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽睦擂。三九已至叶骨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間祈匙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工天揖, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留夺欲,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓今膊,卻偏偏與公主長得像些阅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子斑唬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 我不會問市埋,你愛我嗎黎泣?因為我不需要你的回答。答案再完美也抵不過我自己內(nèi)心的感受和我的直覺缤谎。我不會問抒倚,不代表我不想要肯...
    很認(rèn)真的消遣閱讀 493評論 0 0
  • 今天凌晨,終于把《實習(xí)醫(yī)生格蕾》的頭兩季看完了坷澡。 沒想到這種醫(yī)療劇如此吸引人托呕,讓我已經(jīng)把兩、三個周末的時間都花在這...
    做個讀書人閱讀 2,041評論 12 5
  • 直播應(yīng)用中频敛,RTMP和HLS基本上可以覆蓋所有客戶端觀看 HLS主要是延時比較大项郊,RTMP主要優(yōu)勢在于延時低。 一...
    刺骨寒閱讀 2,438評論 0 11