java包装类Integer缓存认识

    在我前面的博客中,已经写到一篇关于Integer的认识,后来在看的时候发现这篇博客写的有点问题,改起来思路完全不一样了,所以再写一篇来讲解。
    在这里先给一个程序

public class TestInteger {
    public static void main(String[] args) {
        Integer a1 = 100;
        Integer b1 = 100;
        System.out.println(a1==b1);//true

        Integer a2 = 200;
        Integer b2 = 200;
        System.out.println(a2==b2);//false
    }
}

    我们先来阅读一下这个程序,使用了Integer包装类(如果不了解包装类的点击)定义了四个变量a1,b1,a2,b2。这四个变量都是直接量赋值,然后去比较了一下。或许你会认为是两个true,都是一样的数值类型,比较的值相等,肯定是两个true啊。或者是两个false,这是Integer,不是基本类型变量,是引用类型变量,等于号比较的是地址,所以应该是两个false。
    然而结果是一个为true,一个为false。这是为什么?等于号并不是比较数值类型的值,而是基本数据类型的值,引用数据类型的地址,这四个变量很明显就是引用数据类型,比较的肯定是地址,现在不能确定的是变量在内部到底是不是一个地址。这我们就要了解这两行代码执行的底层原理。
    我们用javap -c命令反编译,看看直面量赋值的背后调用了什么方法??
在这里插入图片描述    我们可以看到这个赋值语句背后用的是valueof( )方法,我们在源码中找到有关语句
在这里插入图片描述    在这里我截图一块截了valueof方法中要用到的内部类IntegerCache,我们先来读一下valueof方法,如果i大于 IntegerCache.low 小于 IntegerCache.high的时候,直接返回了cache数组中的某个值,而cache数组在内部类中我们可以看到通过for循环,把-128到127和数组的一一对应起来,不在这个范围内才去创建新的对象。这下我们就理解了为什么会出现上面的结果了,第一组数字100在范围内,直接从数组中返回,所以两次返回的是同一个数组中的元素,而第二组数组不在该范围内,都是通过new创建了新的对象,所以比较地址就会返回false。
    这种把值提前放在数组中遇到的时候直接返回的做法就是java的缓存机制,它的好处就是可以避免重复去创建对象对资源的浪费。举个例子,我买一台电脑,当我用完的时候就离开不再使用,而不是直接扔掉,当我再次使用的时候再到电脑跟前使用便是了,我们都知道电脑很贵的,不是一次性的,这无异于去创建对象的花费,所以这样就很好理解为什么去用缓存了。

猜你喜欢

转载自blog.csdn.net/weixin_42220532/article/details/86567894