今天看《深入理解Java虛擬機》,其中作者留了一段代碼,讓讀者自己試試,運行結(jié)果和我預(yù)想的完全不一致,因此記錄下來,做個總結(jié)。
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println("c == d :"+(c == d));
System.out.println("e == f :"+(e == f));
System.out.println("c == (a + b) :"+(c == (a + b)));
System.out.println("c.equals(a + b) :"+c.equals(a + b));
System.out.println("g == (a + b) :"+(g == (a + b)));
System.out.println("g.equals(a + b) :"+g.equals(a + b));
以上代碼輸出結(jié)果如下:
c == d :true
e == f :false
c == (a + b) :true
c.equals(a + b) :true
g == (a + b) :true
g.equals(a + b) :false
這里有兩個疑惑:
為什么 c == d 但是 e != f?
這其中有兩個原因,一是Integer賦值過程自動裝箱;二是-128~127范圍內(nèi)的Integer的cache。
- 自動裝箱
Integer c = 3
編譯后結(jié)果如下:
Integer c = Integer.valueOf(3);
-
-128~127范圍內(nèi)的Integer的cache
在-128~127范圍內(nèi)的數(shù)據(jù)Integer.valueOf()返回的是同一個對象;
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
}
基于以上兩條,才會出現(xiàn)c == d 但是 e != f這種情況
為什么 g == (a + b) 但是g.equals(a + b) == false ?
這是因為,編譯期間遇到算術(shù)運算符會自動拆箱(??==運算在不遇到算術(shù)運算符的情況下不會自動拆箱):
System.out.println("g == (a + b) :"+(g == (a + b)));
編譯結(jié)果如下:
System.out.println("g == (a + b) :"+(g.intValue() == (a.intValue() + b.intValue()));
因此,才會出現(xiàn)g == (a + b)
至于g.equals(a + b) == false,完全是由于對象類型不一致(Long和Integer)