Java的自动装箱和拆箱
Java的自动装箱和拆箱
1、什么是装箱和拆箱?
装箱:将基本数据类型转换为包装数据类型
拆箱:将包装数据类型转换为基本数据类型
在JDK5之前,java是没有自动装箱和拆箱功能的。所以,那个时候想要创建包装类对象必须要这样:
Integer i = new Integer(1);
Double d = new Double(1.0);
而从JDK5开始,java中就新增了自动装箱和拆箱功能
Integer i = 1;
Double d = 1.0;
2、如何实现?
通过包装类中的 valueOf(xxx) 方法和 xxxValue() 方法实现(xxx指的是基本数据类型,比如 valueOf(int),intValue() )
3、面试时常见问题
Integer
Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
请问以上代码的输出结果是什么?
true
false
我想大部分人对第一个结果没什么问题,但第二个为什么就是false
了呢?这个时候,我们就就去看看Integer的源码了
valueOf(int)
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 property
int 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_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;
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() {}
}
以上代码说明Integer在创建对象的时候,如果数值是在[-128,127]的范围内,就会返回一个IntegerCache.cache[i + (-IntegerCache.low)]的引用,否则就会返回新的对象
而在这一道题中的i3和i4已经大于127了,所以会返回不同的两个对象,所以它们的地址值不同,==的结果就为false了
Double
Doubel d1 = 127.0;
Doubel d2 = 127.0;
Doubel d3 = 128.0;
Doubel d4 = 128.0;
System.out.println(d1 == d2);
System.out.println(d3 == d4);
那么变为Double后结果有变化吗?
false
false
我们可以查看Double的valueOf()方法
public static Double valueOf(double d) {
return new Double(d);
}
看得出来,它是直接返回一个新的对象,这就解释了为什么两个都是false了
总结:
当看了剩余的其它包装类的valueOf()方法后,我们可以得知:
Integer、Byte、Short、Long这几个类调用valueOf()方法时都会判断传入的值是否处于【-128~127】之间,如果处于则返回缓存中已经存在的引用,如果不在范围内则会返回一个新的对象
Character的范围是【0~127】
Float、Double则是直接返回新的对象