2014年去某公司筆試的時候遇到這麼一道題:java
public class Test { public static void main(String[] args) { Integer int1 = Integer.valueOf("100"); Integer int2 = Integer.valueOf("100"); System.out.println(int1 == int2); } }
問打印的結果的多少? 可是我回答的是false, 後來仔細想一想應該沒有這個簡單,就翻了下JDK的源碼,發現:面試
public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
發現裏面另有玄機,多了個IntegerCache類:緩存
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() {} }
原來Integer把-128到127(可調)的整數都提早實例化了。 這就解釋了那道面試題的答案,原來你無論建立多少個這個範圍內的Integer用ValueOf出來的都是同一個對象。服務器
可是爲何JDK要這麼畫蛇添足呢? 咱們仔細想一想, 淘寶的商品大多數都是100之內的價格, 一天後臺服務器會new多少個這個的Integer, 用了IntegerCache,就減小了new的時間也就提高了效率。同時JDK還提供cache中high值得可配置,優化
這無疑提升了靈活性,方便對JVM進行優化。spa
參考Long的源碼:code
private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
Long也作了緩存,只是沒有提供調整機制, 在Short中相似:orm
private static class ShortCache { private ShortCache(){} static final Short cache[] = new Short[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Short((short)(i - 128)); } }