java基础之自动拆装箱和整型缓存机制

自动装箱: 就是将基本数据类型自动转换成对应的包装类。

自动拆箱:就是将包装类自动转换成对应的基本数据类型。

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设置。

同样,ByteShortLong有对应的缓存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循环中有大量拆装箱操作,会比较浪费资源,应该避免。

 

你可能感兴趣的:(Java,java)