1,什么是自动装箱和拆箱?
Java中有8种基本数据类型:1字节=8bit(位)java
对应的包装类型为:Byte、Short、Integer、Long、Float、Double、Character、Boolean数组
包装类型的对象存在与堆空间中。基本数据类型的存在是为了更有效率地方便计算。缓存
JDK1.5以前,这两种类型不能直接转换。从JDK1.5开始,为了方便开发,开始支持这两种类型直接转换。从基本数据类型到包装类型称为装箱,从包装类型到基本数据类型称为拆箱。code
Integer i = 3; // 自动装箱 int a = i; // 自动拆箱
2,自动装箱和拆箱的源码实现:
先看int和Integer的转换:orm
Integer类有个属性: private final int value;
对象
自动拆箱会调用Integer.intValue()
,源码:开发
public int intValue() { return value; }
自动装箱会调用Integer.valueOf()
,源码:get
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) // 若是i在IntegerCache.low和IntegerCache.high的范围内 return IntegerCache.cache[i + (-IntegerCache.low)]; //返回IntegerCache.cache[]中的Integer数据 return new Integer(i); // 若是不在缓存范围内,新建一个Integer对象 }
IntegerCache是Integer的一个内部私有类,源码:源码
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"); // 能够经过启动参数-Djava.lang.Integer.IntegerCache.high=127来指定 if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); // 最大值不能小于127 i = Math.max(i, 127); // 最大值不能超过Integer.MAX_VALUE=2147483647 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // 若是指定的参数不能转换为int类型数据,直接跳过。 } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) // 为缓存数组赋值 cache[k] = new Integer(j++); assert IntegerCache.high >= 127; } private IntegerCache() {} }
其余的整形类型和字符型与此相似,均有缓存。Byte,Short,Long 有固定范围: -128 到 127。对于 字符型Character, 范围是 0 到 127。
除了 Integer 能够经过参数改变范围外,其它的都不行。
自动装箱时若是是缓存边界以外的数据,则新建立对象,不然返回缓存中的对象。
浮点型数据没有缓存。(可能由于浮点型数据没有范围。。。)it
布尔型Boolean的装箱和拆箱源码: Boolean类有3个属性:
public static final Boolean TRUE = new Boolean(true); public static final Boolean FALSE = new Boolean(false); private final boolean value;
自动装箱的源码:
public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
自动拆箱的源码:
public boolean booleanValue() { return value; }
参考资料: