自动装箱: 就是将基本数据类型自动转换成对应的包装类。
自动拆箱:就是将包装类自动转换成对应的基本数据类型。
Integer a = 10; //自动装箱
int i = a; //自动拆箱
//自动装箱是通过valueOf方法实现的
Integer a = Integer.valueOf(10);
//自动拆箱是通过intValue方法实现的
int i = a.intValue();
场景一、将基本数据类型放入到集合中时,进行自动装箱
List li = new ArrayList<>();
for (int i = 1; i < 50; i ++){
//相当于li.add(Integer.valueOf(i));
li.add(i);
}
场景二、包装类型和基本类型的大小比较,进行自动拆箱
Integer a=1;
//System.out.println(a.intValue()==1?"等于":"不等于");
System.out.println(a==1?"等于":"不等于");
Boolean bool=false;
//System.out.println(bool.booleanValue?"真":"假");
System.out.println(bool?"真":"假");
场景三、包装类型的运算,进行自动拆箱
//Integer i = Integer.valueOf(10);
Integer i = 10;
//Integer j = Integer.valueOf(20);
Integer j = 20;
//System.out.println(i.intValue() + j.intValue());
System.out.println(i+j);
Integer a1 = 50;
Integer a2 = 50;
Integer b1 = 500;
Integer b2 = 500;
//true
System.out.println(a1==a2);
//false
System.out.println(b1==b2);
//true
System.out.println(a1.equals(a2));
//true
System.out.println(b1.equals(b2));
首先,"=="比较的是对象指向的地址,也就是相同的对象,封装数据类型中"equals"方法比较的是值的大小。
很显然,a1和a2是两个不同的对象,那么a1==a2理应同b1==b2结果一样是false才对,但是事实上却是true,原因是Integer缓存机制。java5在Integer中引入的一个有助于节省内存、提高性能的功能IntegerCache,整型对象通过使用相同的对象引用实现了缓存和重用。这个缓存会在Integer类第一次被使用的时候被初始化出来。
当需要进行自动装箱时,如果数字在-128至127之间,会直接使用缓存中的对象,而不是重新创建一个对象。
其中最大值可以通过java.lang.Integer.IntegerCache.high
设置。
同样,Byte
, Short
, Long有对应的缓存
ByteCache、ShortCache、LongCache,范围同IntegerCache
都是-128至127,Character也有缓存CharacterCache,范围是0到127。但是只有IntegerCache可以设置最大值。
1、IntegerCache适用于整数值区间-128 至 +127。
2、只适用于自动装箱。使用构造函数创建对象不适用,如下:
Integer a1 = new Integer(50);
Integer a2 = new Integer(50);
Integer a3 = 50;
//false
System.out.println(a1==a2);
//false
System.out.println(a1==a3);
3、拆箱时如果包装类型为null,则会导致空指针异常
Integer a = null;
//java.lang.NullPointerException
System.out.println(a+1);
4、由于缓存的原因导致有些封装类型数值对应的对象是一样的,但大多数又不是同一个对象,所以对象的比较通常使用equals方法,应避免“==”比较导致的问题
5、如果一个for循环中有大量拆装箱操作,会比较浪费资源,应该避免。