例:
package deep;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNextInt()) {
int ii = input.nextInt();
System.out.println("====" + ii + "的相等判斷====");
// 兩個通過new產生的Integer對象
Integer i = new Integer(ii);
Integer j = new Integer(ii);
System.out.println("new產生的對象:" + (i == j));
// 基本類型轉爲包裝類型後比較
i = ii;
j = ii;
System.out.println("基本類型轉換的對象:" + (i == j));
// 通過靜態方法生成一個實例
i = Integer.valueOf(ii);
j = Integer.valueOf(ii);
System.out.println("valueOf產生的對象:" + (i == j));
}
}
}
運行結果:
127
====127的相等判斷====
new產生的對象:false
基本類型轉換的對象:true
valueOf產生的對象:true
128
====128的相等判斷====
new產生的對象:false
基本類型轉換的對象:false
valueOf產生的對象:false
555
====555的相等判斷====
new產生的對象:false
基本類型轉換的對象:false
valueOf產生的對象:false
很不可思議呀,數字127的比較結果竟然與其他兩個數字不同,它的裝箱動作所產生的對象竟然是同一個對象,valueOf產生的也是同一個對象,但是大於127的數字128和555在比較過程中所產生的卻不是同一個對象,這是爲什麼?我們一個一個來解釋:
(1)new產生的Integer對象
new聲明的就是要生成一個新的對象,沒二話,這是兩個對象,地址肯定不等,比較結果爲false。
(2)裝箱生成的對象
對於這一點,首先要說明的是裝箱動作是通過valueOf方法實現的,也就是說後兩個算法是相同的,那結果肯定也是一樣的,現在的問題是:valueOf是如何生成對象的呢?我們來閱讀以下Integer.valueOf的實現代碼:
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
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() {}
}
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
以上代碼的意思已經很明瞭了,如果是-128到127之間的int類型轉換爲Integer對象,則直接從cache數組中獲得,cache是IntegerCache內部類的一個靜態數組,容納的是-128到127之間的Integer對象。通過valueOf產生包裝對象時,如果int參數在-128和127之間,則直接從整型池中獲得對象,不在該範圍的int類型則通過new生成包裝對象。
明白了這一點,要理解上面的輸出結果就迎刃而解了,127的包裝對象是直接從整型池中獲得的,不管你輸入多少次127這個數字,獲得的對象都是同一個,那地址當然都是相等的。而128、555超出了整型池範圍,是通過new產生一個新的對象,地址不同,當然也就不相等了。
以上的解釋也就是整型池的原來,整型池的存在不僅僅提高了系統性能,同時也節約了內存空間,這也是我們使用整型池的原因,也就是在聲明包裝對象的時候使用valueOf生成,而不是通過構造函數來生成的原因。順便提醒大家,在判斷對象是否相等的時候,最好是用equals方法,避免用“==”產生非預期結果。