包装类缓存池 ----JDK1.8
本文以Integer为例 (看了Long的分析之后)
结构
-
类的结构
public final class Integer extends Number implements Comparable<Integer>
继承了Number类
Number类定义了很多由当前包装类转为基本类型的方法,每个包装类都继承该方法并实现
//实现了Comparable接口的compareTo方法 public int compareTo(Integer anotherInteger) { return compare(this.value, anotherInteger.value); } public static int compare(int x, int y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); }
-
缓存池源代码
//Integer缓存池类 私有的静态内部类 缓存的值是-128-127 [-128,127] private static class IntegerCache { static final int low = -128; static final int high;//缓存的大小可以由-XX:AutoBoxCacheMax=<size>选项控制,应该是vm的属性设置,现在还搞不懂 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) {//这个if中的就是属性配置高值 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;//找到大的h cache = new Integer[(high - low) + 1];//配置缓存池数组的大小 +1 是因为还有个0 int j = low;//缓存从-128开始 for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++);//设置值进入缓存,就是初始化,阿里Java手册要求for带上大括号 // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127;//断言机制,如果后面>=为false则抛出异常,为true正常执行 } private IntegerCache() {} }
Integer类的方法
-
valueOf(int i) 这个方法涉及到了自动装箱(自动帮你调用valueOf方法)
Integer i=100;//一个基本类型100 为什么可以直接赋值到一个类? //debug断点跟踪一下,发现会自动跳转到valueOf这个方法,new一个Integer类
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high)//判断i是否在缓存池中,IntegerCache.low这个值是固定的为什么不直接用-128呢?可能是对称起来好看 return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
//自动拆箱
int a = i; //这里帮你自动调用了 public int intValue() { return value; }