装箱和拆箱:
- 装箱:基本类型转换成包装类型,使用的是 valueOf() 方法
- 拆箱:包装类型转换成基本类型,使用的是 intValue(),longValue(),… 方法
自动拆箱引发的空指针:
- 变量赋值自动拆箱出现空指针
- 方法传参时自动拆箱出现空指针 ```java public static int add(int x, int y) { return x + y; }
public static void main(String[] args) { // 1.变量赋值自动拆箱出现空指针 Long count = null; long count_ = count;
// 2.方法传参时自动拆箱引发的空指针Integer left = null;Integer right = null;add(left, right);
}
基本类型和包装类型的区别:<br /><br />注意事项:- Integer 包装类中有个静态内部类 IntegerCache,用于缓存 -128 到 127(默认)的Integer 实例,通过 valueOf 方法能够看到,再次创建值在 -128 到 127 区间的 Integer实例时,会复用缓存中的实例,也就是直接指向缓存中的 Integer 实例(这里的创建不包括使用 new 创建,new 创建会直接创建新对象)```java// 直接使用字面量,会调用 Integer.valueOf() 进行包装,即-128到127的Integer从缓存池中获取Integer a = 128;Integer b = 128;a == b; // falseInteger c = 127;Integer d = 127;c == d; // true// newInteger e = new Integer(127);Integer f = new Integer(127);e == f; // false// 在基本类型和包装类型进行比较时,包装类会拆箱,比较的是值int a = 127;Integer b = 127;Integer c = new Integer(127);a == b; // truea == c; // true
Byte、Short、Integer、Long、Character也具有缓存机制。其中 Byte,Short,Integer,Long为 -128 到 127,Character范围为 0 到 127。如 Long 类中的缓存类源码:
private static class LongCache {private LongCache(){}static final Long cache[] = new Long[-(-128) + 127 + 1];// 通过静态代码中完成缓存的初始化,即在类生命周期的初始化阶段执行static {for(int i = 0; i < cache.length; i++)cache[i] = new Long(i - 128);}}
Integer 的缓存上界可以通过 jvm 参数 -XX:AutoBoxCacheMax=size 指定,除此之外,其他的缓存不能更改
规避自动拆箱引发空指针的建议:
- 对于不确定的包装器类型,一定要校验是否为 NULL
- 对于变量的属性,优先使用包装类型,方便统一判断,即 xxx != null
