?一.Integer類型對象之間大小比較
????1.使用new Integer()創(chuàng)建的對象 :
首先,我們知道,在java中,基本類型之間是可以做大小比較的,例如int i=1,int j=2,是可以直接使用關(guān)系運(yùn)算符<、>、==等符號來做比較的。但在實(shí)際開發(fā)中,基本類型的包裝類更為常用,那么包裝類型的比較運(yùn)算是如何呢?
在main方法中執(zhí)行下面Java代碼
Integer?i?=?new?Integer(100);
Integer?j?=?new?Integer(100);
System.out.println(i==j);
有人可能會說,jdk1.5以后,基本類型和包裝類型之間是可以自由轉(zhuǎn)換的,那么Integer對象也可以直接用關(guān)系運(yùn)算符來做比較,但實(shí)際情況并非這樣。執(zhí)行上述代碼,打印結(jié)果是:
?????false
????其實(shí)原因很簡單,上述代碼中我們執(zhí)行了兩次new,所以創(chuàng)建了兩個(gè)Integer型的對象,對象之間的“==”符是用來比較是否是一個(gè)對象的兩個(gè)引用(即比較地址是否相同),上述代碼中,兩次new出來的對象地址顯然是不可能相同的,故打印結(jié)果是false。
那么對于“<”、“>”這樣的運(yùn)算符呢?執(zhí)行下面代碼:
Integer?i?=?new?Integer(100);
Integer?j?=?new?Integer(300);
System.out.println(i<j);
打印結(jié)果是true,經(jīng)過實(shí)驗(yàn),對于“<”、“>=”符號也是一樣的。
結(jié)論:使用new關(guān)鍵字創(chuàng)建的包裝類型對象,不可以直接使用“==”來做大小比較,但可以使用<、>、<=、>=來做大小比較。
????2.使用Integer.valueOf()創(chuàng)建的對象
當(dāng)然,創(chuàng)建包裝類型對象不一定非要使用new關(guān)鍵字,以Integer為例,我們可以使用Integer.valueOf()方法創(chuàng)建Integer對象。那么這種方法創(chuàng)建的對象如何做大小比較呢?
執(zhí)行下面的代碼:
Integer?i?=?Integer.valueOf(100);
Integer?j?=?Integer.valueOf(100);
System.out.println(i==j);
執(zhí)行后,我們發(fā)現(xiàn),打印結(jié)果是true。
根據(jù)這個(gè)結(jié)果,我們是否可以認(rèn)為,通過valueOf方法創(chuàng)建的對象,可以直接使用關(guān)系運(yùn)算符做比較呢?
? ? ? ? ? 先別急,再執(zhí)行一段代碼:
? ? ? ? ? Integer?i?=?Integer.valueOf(400);
? ? ? ? ? Integer?j?=?Integer.valueOf(400);
? ? ? ? ? System.out.println(i==j);
這段代碼,打印結(jié)果居然是false!那么對于<、>、<=、>=這幾個(gè)符號呢?通過實(shí)驗(yàn),得出的結(jié)論和1中相同,這幾個(gè)符號仍然可以直接使用。
結(jié)論:通過valueOf方法創(chuàng)建的Integer對象,也不能隨便使用“==”比較大小,但可以使用<、>、<=、>=來做大小比較。
???3.使用基本類型賦值創(chuàng)建的對象
相比前兩種方法,我們平時(shí)更常用的是直接將基本類型對象賦值給包裝類型(即自動裝箱),比如Integer i=100這樣的語法。那么通過這種方法創(chuàng)建的對象,可否使用關(guān)系運(yùn)算符來比較大小呢?
Integer?i?=?100;
? ? ? ? ? Integer?j?=?100;
? ? ? ? ? System.out.println(i==j);
執(zhí)行上面的代碼,發(fā)現(xiàn)打印結(jié)果是true。當(dāng)然有了2中的經(jīng)驗(yàn),我們使用400這個(gè)數(shù)來再試一次:
? ? ? ? ? Integer?i?=?400;
? ? ? ? ? Integer?j?=?400;
? ? ? ? ? System.out.println(i==j);
?????執(zhí)行這段代碼后,發(fā)現(xiàn)和2中情況一樣,仍然打印false;
?????通過實(shí)驗(yàn),對于<、>、<=、>=這幾個(gè)符號,和上面的情況都是一樣的。
結(jié)論:使用Integer i = 400這種方法創(chuàng)建的包裝類對象,也不能用“==”來比較大小,但可以使用<、>、<=、>=來做大小比較。
?????這些現(xiàn)象是什么原因?qū)е碌哪??請看下面的分析?/p>
二.Integer對象不同創(chuàng)建方法之間的區(qū)別
????上文得出的三個(gè)小結(jié)論,都說明了一個(gè)問題,包裝類型是不能夠隨便使用關(guān)系運(yùn)算符比較大小的,針對三種創(chuàng)建對象的方法,原因分析如下:
????首先,對于new關(guān)鍵字創(chuàng)建的包裝類對象,原因在上文已經(jīng)說過了,兩次new得到的對象引用地址是不同的,不能使用“==”關(guān)鍵字做大小比較。而使用“<”和“>”等運(yùn)算符時(shí),包裝類型會調(diào)用valueOf方法,將運(yùn)算符兩邊的對象都轉(zhuǎn)換為基本類型后再做比較。這就是為何“==”不能使用而<、>、<=、>=這幾個(gè)符號可以使用的原因。
????第二,使用valueOf方法創(chuàng)建的Integer對象,使用“==”符號時(shí),運(yùn)行結(jié)果有時(shí)候正確,有時(shí)候不正確。查看valueOf方法的源碼,如下:
??????????public?static?Integer?valueOf(int?i)?{
???????????????if(i?>=?-128?&&?i?<=?IntegerCache.high)
???????????????????return?IntegerCache.cache[i?+?128];
???????????????else
???????????????????return?new?Integer(i);
????????}
??????通過看源碼能夠知道,整數(shù)類型在-128~127之間時(shí),會使用緩存,造成的效果就是,如果已經(jīng)創(chuàng)建了一個(gè)相同的整數(shù),使用valueOf創(chuàng)建第二次時(shí),不會使用new關(guān)鍵字,而用已經(jīng)緩存的對象。所以使用valueOf方法創(chuàng)建兩次對象,若對應(yīng)的數(shù)值相同,且數(shù)值在-128~127之間時(shí),兩個(gè)對象都指向同一個(gè)地址。最后,使用Integer i = 400這樣的方式來創(chuàng)建Integer對象,與valueOf方法的效果是一樣的,不再贅述??傊b類對象不可使用“==”符做比較運(yùn)算,如果要進(jìn)行比較運(yùn)算時(shí),最好使用java類庫中的compareTo方法。