Integer及Integer缓冲池
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