网站建设最好的书籍是/自己的网站怎么做seo
自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。JDK1.5后,Java引入了自动装箱(autoboxing)/拆箱(unboxing)。
自动装箱:
基本类型的数据处于需要对象的环境中时,会自动转为“对象”。
我们以Integer为例:在JDK1.5以前,这样的代码 Integer i = 5 是错误的,必须要通过Integer i = new Integer(5); 这样的语句来实现基本数据类型转换成包装类的过程;而在JDK1.5以后,Java提供了自动装箱的功能,因此只需Integer i = 5这样的语句就能实现基本数据类型转换成包装类,这是因为JVM为我们执行了Integer i = Integer.valueOf(5)这样的操作,这就是Java的自动装箱。
自动拆箱:
每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法。
自动装箱/拆箱例子:
package yzy.commonclasses;
/** 测试自动装箱和拆箱*/
public class testBinngAndDevanning {public static void main(String[] args) {Integer a = 666; //自动装箱 相当于Integer d = Integer.valueOf(666); int b = a; //自动拆箱 相当于int b = a.intValue(); Integer c = null;//int d = c; //相当于int d = c.intValue(); /* error: NUllpointerException* 说明编译器底层通过包装类对象c调用了成员方法* 装箱和拆箱所以还是调用了valueOf方法和intValue方法*///缓冲区Integer in1 = -128; //Integer in1 = Integer.valuesOf(-128);Integer in2 = -128;System.out.println(in1 == in2);//true 因为123在缓存范围内System.out.println(in1.equals(in2));//true/* 在基本整数值的范围在[-128, 127]中时进行转包装类对象* valuesOf函数会返回对应的缓冲数组的一个元素,* 因此包装类在值相同且在[-128, 127]范围中时引用对象是同一个* 所以in1和in2引用同一个对象*/Integer in3 = 1234;Integer in4 = 1234;System.out.println(in3 == in4);//false 因为1234不在缓存范围内System.out.println(in3.equals(in4));//true}
}
Integer类valueof源码:
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
IntegerCache类源码:
private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint 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_VALUEh = 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() {}
}
总结自动装箱/拆箱:
自动装箱过程是通过调用包装类的valueOf()方法实现的,而自动拆箱过程是通过调用包装类的 xxxValue()方法实现的(xxx代表对应的基本数据类型,如intValue()、doubleValue()等)。
自动装箱与拆箱的功能事实上是编译器来帮的忙,编译器在编译时依据您所编写的语法,决定是否进行装箱或拆箱动作
Integer类valueof在整数范围是[-128, 127]时,会返回数组元素IntegerCache类中cache数组的一个元素
而cache数组是IntegerCache类中的私有数据成员
cache数组创建过程如图:
cache数组是包装类Integer类型数组,通过以上cache数组创建源码可以看到,其中cache数组的每一个元素引用的是包装类Integer的实例对象都是引用类型,那么只要在[-128, 127]
范围的一个整数转换为多个包装类引用对象那么指向的都是相同的对象