Integer中有個靜態內部類IntegerCache,里面有個cache[],也就是Integer常量池,常量池的大小為一個字節(-128~127)。
源碼為(jdk1.8.0_101)
1 private static class IntegerCache { 2 static final int low = -128; 3 static final int high; 4 static final Integer cache[]; 5 6 static { 7 // high value may be configured by property 8 int h = 127; 9 String integerCacheHighPropValue = 10 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); 11 if (integerCacheHighPropValue != null) { 12 try { 13 int i = parseInt(integerCacheHighPropValue); 14 i = Math.max(i, 127); 15 // Maximum array size is Integer.MAX_VALUE 16 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); 17 } catch( NumberFormatException nfe) { 18 // If the property cannot be parsed into an int, ignore it. 19 } 20 } 21 high = h; 22 23 cache = new Integer[(high - low) + 1]; 24 int j = low; 25 for(int k = 0; k < cache.length; k++) 26 cache[k] = new Integer(j++); 27 28 // range [-128, 127] must be interned (JLS7 5.1.7) 29 assert IntegerCache.high >= 127; 30 } 31 32 private IntegerCache() {} 33 }
當創建Integer對象時,不使用new Integer(int i)語句,大小在-128~127之間,對象存放在Integer常量池中。
例如:Integer a = 10;
調用的是Integer.valueOf()方法,代碼為
1 public static Integer valueOf(int i) { 2 if (i >= IntegerCache.low && i <= IntegerCache.high) 3 return IntegerCache.cache[i + (-IntegerCache.low)]; 4 return new Integer(i); 5 }
這也是自動裝箱的代碼實現。
測試Integer的特性:
1 public class TestInteger { 2 public static void main(String[] args) { 3 //jdk1.5后 虛擬機為包裝類提供了緩沖池,Integer緩沖池的大小為一個字節(-128~127); 4 //創建 1 個對象,存放在常量池中。引用c1,c2存放在棧內存中。 5 Integer c1 = 1; 6 Integer c2 = 1; 7 System.out.println("c1 = c2 ? " + (c1 == c2)); //true 8 9 //創建 2 個對象,存放在堆內存中。2 個引用存放在棧內存中。 10 Integer b1 = 130; //130不在(-128~127)之間 11 Integer b2 = 130; 12 System.out.println("b1 = b2 ? " + (b1 == b2)); //false 13 14 //創建2個對象,存放在堆內存中。 15 Integer b3 = new Integer(2); 16 Integer b4 = new Integer(2); 17 System.out.println("b3 = b4 ? " + (b3 == b4)); //false 18 //下面兩行代碼證明了使用new Integer(int i) (i 在-128~127之間)創建對象不會保存在常量池中。 19 Integer b5 = 2; 20 System.out.println("b3 = b5 ? " + (b3 == b5)); //false 21 22 //Integer的自動拆箱,b3自動轉換成數字 2。 23 System.out.println("b3 = 2 ? " + (b3 == 2)); //true 24 Integer b6 = 210; 25 System.out.println("b6 = 210 ? " + (b6 == 210)); //true 26 } 27 }
打印結果為:
c1 = c2 ? true b1 = b2 ? false b3 = b4 ? false b3 = b5 ? false b3 = 2 ? true b6 = 210 ? true