目录
本质区别
例:Integer与int
1、默认值
包装类型默认值为null,基本类型默认值为0
包装类可以接收null
2、泛型支持
包装类型可以支持泛型,例如:List<Integer> list
基本类型不支持
3、内存占用
包装类型,new一个对象,真实数据存放在堆中,栈中存放堆地址
基本类型直接存储在栈中
4、性能
基本类型无需拆装箱
包装类型,1.5以后有自动拆装箱
以Integer为例,装箱:Integer.valueOf,自动装箱有缓存机制,在[-128,127]区间内,则直接取缓存的值,不需要new对象。拆箱:Integer#intValue
static final Integer cache[];
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
8种基本类型:byte、short、int、long、float、double、char、boolean
缓存机制:Byte、Short、Integer、Long、Character
其中,整型基本类型对应的包装类都有[-127,128]区间内的缓存机制,字符型包装类缓存机制范围为[0,127]
//byte:1字节 所有值都已缓存
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
//short:2字节
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);
}
//long:8字节
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
//char:2字节
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
结论
综上所述,虽然包装类型提供了缓存机制来减少拆装箱带来的性能消耗,但是在缓存范围外的数据包括内存方面的占用情况,所以说要优先使用基本类型,有不支持的场景则考虑包装类。
例如,阿里巴巴规范里提到的,数据库的查询结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险。但如果数据库表结构里字段明确定义为not null,则使用基本类型
例如,与前端交互时,属性返回0 与 null 是可能是两种意义,这个就需要跟根据业务场景来确定了