首先給大家看一道面試題:
Integer a=100,b=100,c=200,d=200; System.out.println(a==b); System.out.println(c==d);
題的大概內容與這個類似,就是比較兩個 int 包裝類的值
很多小伙伴一看題,想都不想:true true 。。
你有沒有想過,要是這么 low 的題,面試官是考你什么呢?
相信看過 jdk 源碼的小伙伴一定知道結果不是這樣的
小編先公布結果,再給大家解釋下原因
第一個輸出語句結果是:true
第二個輸出語句結果是:false
很多人看到這個結果有點差異,就連我自己剛接觸的時候也是比較納悶的,所以小編的好奇心就帶着小編過去點了一下
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ 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() {} }
這個就是 java8 中的 Integer 類中的一個內部緩存類(其他版本的jdk實現有可能不一樣但是效果都是一樣的),這個類的作用就是將 -128~127 之間的整型做了一個緩存
這個東西注釋里已經寫的比較清楚了,緩存在第一次使用時初始化,可以使用 -XX:AutoBoxCacheMax=(SIZE) VM 啟動參數 來改變改變之后的緩存區間為 [-128~SIZE]
具體的作用,小編也不是很清楚,有可能是經過統計,使用 -128~127 之間范圍的整型比較頻繁,所以做了個緩存吧(這個只是小編的推測,還望大佬多多指教)
其實不止是 Integer ,在 Java 中所有的整型都是有緩存的,在 Byte 中也是有的,這個緩存的大小正好也是 Byte 的范圍
所以,小伙伴們,以后遇到這樣的“坑”果斷的跳過,這就是看多看源碼的好處,為什么大廠要求源碼必看,養成好習慣大廠不是夢!!
下面給大家拓展一下:
Integer i1 = 12;//反編譯后同i3一樣 Integer i2 = new Integer(12);//強制 new Integer i3 = Integer.valueOf("12");//如果在緩存范圍內,直接返回緩存的值;如果大於或者小於緩存范圍,才會 new int i4 = 12;//基本類型,只會和自己的包裝類比較只會比較值(看值一樣就是true) System.out.printf("i1==i2: %s \n", (i1 == i2));//false System.out.printf("i1==i3: %s \n", (i1 == i3));//true System.out.printf("i1==i4: %s \n", (i1 == i4));//true System.out.printf("i2==i3: %s \n", (i2 == i3));//false System.out.printf("i2==i4: %s \n", (i2 == i4));//true System.out.printf("i3==i4: %s \n", (i3 == i4));//true