1、简介
装箱:自动把基本类型转化为包装器类型
拆箱:自动把包装器类型转化为基本类型
2、主要对应的包装器类型
byte (1字节) Byte
short (2字节) Short
int (4字节) Integer
long (8字节) Long
float (4字节) Float
double (8字节) Double
char (2字节) Char
boolean () Boolean
3、实现
以Integer为例:装箱的时候自动调用的是Integer的valueOf(int)方法。拆箱的时候自动调用的是Integer的intValue方法,其他类似。
Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。例如Short,如果在-128到127之间,会走ShortCache,超过这个范围会new对象。所以做比较时,在-128到127之间可以用“==”,超过这个范围需要用equals,否则返回false。
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
Double、Float的valueOf方法的实现是类似的,例如Double,调用的valueOf(String s):
public static Double valueOf(String s) throws NumberFormatException {
return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue());
}
public static Double valueOf(double d) {
return new Double(d);
}
4、缓存数据
Integer、Short、Byte、Character、Long这几个类中都有个内部缓存类,Double、Float的类中没有。
Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行
以Integer为例,缓存类IntegerCache,缓存了-127到128的数据,不管创建多少个这个范围内的Integer用ValueOf出来的都是同一个对象,减少了new的时间也就提升了效率。同时JDK还提供cache中high值得可配置。
Short、Byte、Character、Long类中也实现了类似的缓存类,但是没有提供high值的配置。
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");
if (integerCacheHighPropValue != null) {
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);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
5、==和equals
==基本数据类型比较内容,实质也是比较地址(因为对于基本类型来说,当值相同的时候,地址也是相同的),对象比较比较地址。对于java中的“==”操作符号,jvm会根据两边互相比较的操作数的数据类型,来调用不同的指令。对于于boolean,byte、short、int、long这种整形操作数,会生成 if_icmpne指令,该指令用于比较整形数值是否相等。如果操作数是对象的话,编译器则会生成if_acmpne指令,与if_icmpne相比将i(int)改成了a(object reference)。
equals是Object类中的方法,所有继承Object的类都有此方法。Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。像String中的equals都是对这个方法的重写,比较的是所指向的对象的内容。
6、面试常问的一个问题:
Integer i = new Integer("123")和Integer i = 123;这两种方式的区别
答:第一种方式不会触发自动装箱的过程,直接new对象;而第二种方式会触发装箱过程;