漫話:如何給女朋友解釋為什么Java 中"1000==1000"為false,而"100==100"為true?
- public static void main(String[] args) {
- Integer integer1 = 100;
- Integer integer2 = 100;
- System.out.println(integer1 == integer2);
- Integer integer3 = 1000;
- Integer integer4 = 1000;
- System.out.println(integer3 == integer4);
- }
以上代碼,輸出結(jié)果為:
- true
- false

動拆裝箱
首先,我們在介紹自動拆裝箱之前,修改一下上面的代碼,把變量的類型從Integer改為int,重新執(zhí)行以上代碼:
- public static void main(String[] args) {
- int integer1 = 100;
- int integer2 = 100;
- System.out.println(integer1 == integer2);
- int integer3 = 1000;
- int integer4 = 1000;
- System.out.println(integer3 == integer4);
- }
輸出結(jié)果為:
- true
- true
那么,int和Integer有啥區(qū)別呢?
int是基本數(shù)據(jù)類型,而Integer是包裝類。
因為Java是一種面向?qū)ο笳Z言,很多地方都需要使用對象而不是基本數(shù)據(jù)類型,如在集合中元素必須是對象類型的。
所以,Java種就給所有基本類型提供了對應(yīng)的包裝類,而int對應(yīng)的包裝類就是Integer。
有了基本數(shù)據(jù)類型和包裝類,就需要在他們之間進行轉(zhuǎn)換,把基本類型轉(zhuǎn)成包裝類的過程就做裝箱,反之,叫做拆箱。
在Java SE5中,為了減少開發(fā)人員的工作,Java提供了自動拆箱與自動裝箱功能。
自動裝箱: 就是將基本數(shù)據(jù)類型自動轉(zhuǎn)換成對應(yīng)的包裝類。
自動拆箱:就是將包裝類自動轉(zhuǎn)換成對應(yīng)的基本數(shù)據(jù)類型。
在我們最開始的例子中,我們使用Integer integer1 = 100;定義并初始化一個變量。
這時候就涉及到一次自動裝箱。因為100是基本類型int,而需要把他賦值給包裝類型對象integer1,這時候就進行了一次自動裝箱。
Integer integer1 = 100; 其實是 Integer i = new Integer(10);的簡化寫法,就是因為Java中提供了自動裝箱的功能。
自動裝箱的緩存機制
Java SE的自動拆裝箱還提供了一個和緩存有關(guān)的功能。
為了節(jié)省內(nèi)存和提升性能,Java給多個包裝類型提供了緩存機制,可以在自動裝箱過程中,把一部分對象放到緩存中,實現(xiàn)了對象的復(fù)用。
如Byte、Short、Integer、Long、Character等都支持緩存。
對于Integer,其內(nèi)部有一個IntegerCache的內(nèi)部類。他會對整數(shù)值在-128 至 +127期間的對象進行緩存。這個緩存會在Integer類第一次被使用的時候被初始化出來。以后,就可以使用緩存中包含的實例對象,而不是創(chuàng)建一個新的實例(在自動裝箱的情況下)。
也就是說,當我們對一個值在-128 至 +127期間的數(shù)字進行自動裝箱時,并不是每次都新建一個對象,而是直接從緩存中取出一個緩存對象。
==比較的是什么
知道了自動裝箱和其緩存機制,那么我們接下來看一下,當我們代碼中使用==比較兩個對象的時候,比較的到底是什么?
很多人會認為,對于整數(shù)類型,比較的當然是整數(shù)的值了,但是其實不是的。
Java中的==,比較的時對象的地址,如果兩個對象的地址是同一個,那么就返回true,否則返回false。
所以,因為有了自動裝箱、因為有了緩存機制,因為==比較的是地址。
所以,當對-128 至 +127中的兩個Interger進行比較的時候,因為都是從緩存中取出來的同一個對象,所以對象的地址是一樣的,就返回了true。
而對于1000,因為不在緩存范圍內(nèi),所以每次會新建對象,所以就會返回false。
但是需要注意的是,只有在自動裝箱的時候才會有緩存機制,在構(gòu)造函數(shù)中是和緩存無關(guān)的,如以下代碼:
- Integer integer1 = new Integer(100);
- Integer integer2 = new Integer(100);
- System.out.println(integer1 == integer2);
輸出結(jié)果為
- false
關(guān)于作者:漫話編程,是一個通過漫畫+音頻的形式講解枯燥的編程知識的公眾號。致力于讓編程變得更有樂趣。
本文轉(zhuǎn)載自微信公眾號「漫話編程」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系漫話編程公眾號。