畢業剛工作的時候,帶我的小師傅給我說判斷相等使用equals不要使用==,第一次寫java的我照辦了,但是不清楚爲什麼,之後還是決定真正瞭解一下java本身。於是開始看jdk源碼。這裏以Integer爲例
equal
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
可以看到equals方式是對Integer的內容進行比較,用equals確實沒有問題
那==是怎麼回事呢?
一般都知道在各類語言中都來比對地址的,不讓用我可以理解,但是爲什麼在項目中又看到有人用到呢?並且也沒什麼問題?地址是一樣的?不過不應該啊,於是開始看Integer在java中賦值過程是怎麼回事
java中Integer的賦值過程。
Integer integer1=123;
看字節碼文件發現
可以看到Integer是調用了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[];
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) {
try {
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);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
點開源碼一下就瞭解怎麼回事了,這不就是工作中緩存熱點數據麼。
原來它會在內存中緩存一份熱點數據-127-128,賦值過來如果在這個範圍內直接返回對應座標下的對象。所以說我們的數據只要在設置的範圍內,我們拿到的都說一個對象,地址當然相同,用==判斷一定也沒有問題。
又大概看了一下其他基礎類型的包裝類Long、Byte、Short都是類似設計,
Double、float直接創建新對象