java的自动装箱与拆箱
包装类:
java中有8种基本数据类型对应8个包装类,包装类解决了基本数据类型无法面向对象编辑的问题,包装类自事了许多方法。
基本数据类型与包装类对应表
基本数据类型 | 包装类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
**自动装箱:**装箱就是自动将int类型转成Integer类型
**自动拆箱:**装箱就是自动将Integer类型转成int类型
装箱
Integer inte = 10; //int类型的10会自动转成Integer类型
Integer inte = Integer.valueOf(10);
拆箱
int in = inte; Integer类型的inte会自动转成int类型
int in = inte.intValue();
问题1
下面代码中Object泛型的List集合,却可以添加 “int” 类型的数据。
List<Object> obj = new ArrayList<>();
obj.add(10);
obj.add(20);
System.out.println(obj.toString()); //[10, 20]
因为添加的int类型数据会自动装箱成Integer类型。//Object是所有类的超类
这就为什么存放Object泛型的List集合,却可以添加 “int” 类型。
问题2
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = new Integer(100);
Integer i4 = 200;
Integer i5 = 200;
System.out.println(i1 == i2); //true
System.out.println(i1 == i3); //false
System.out.println(i4 == i5); //false
为什么 i1 == i2 是true, 而 i4 == i5是false呢?
因为装箱时会调用静态方法valueOf();看下valueOf()方法。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
valueof方法中会先判断当前拆箱的值是否在某个范围内,在范围内的话就返回cache数组中的值,不在就new一个Integer返回。
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() {}
}
此类中初始化了cache数组,创建[-128, 127]的Integer对象存入数组中;所以数值“100”装箱时是数组中的引用。