常量池与Integer类的缓存机制

在说这些之前,先说一下在Java中,equals方法和==都有比较值的作用,具体区别如下:

1)对于==,比较的是值是否相等

如果作用于基本数据类型的变量,则直接比较其存储的值是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址是否相等。

其实==比较的不管是基本数据类型,还是引用数据类型的变量,比较的都是值,只是引用类型变量存的值是对象的地址

2)对于equals方法,比较的是是否是同一个对象

首先,equals()方法不能作用于基本数据类型的变量;
另外,equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,所以说所有类中的equals()方法都继承自Object类,在没有重写equals()方法的类中,调用equals()方法其实和使用==的效果一样,也是比较的是引用类型的变量所指向的对象的地址,不过,Java提供的类中,有些类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值,比如String类。

Integer类的缓存机制

Java 5开始整型类型加入对应的缓存类型,这里以Integer为例,查看源码很容易发现Interger有一个私有的静态内部类,那么int类型在自动装箱的时候会调用Integer的valueOf的方法,源码中可以发现如果值在【-128—127】之间就不会创建新的对象,而是从IntegerCache在初始化的cache数组中去取相应的值,cache数组的范围初始化的时候就确定了范围【-128—127】,所以会直接从中取值,从而节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用 ,从java 6开始IntegerCache的最大值high可以自定义设置,可以通过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改 ,但也不会大于Integer.MAX_VALUE最大值。观察如下代码:

/**
         *输出:true, true
         */
        Integer a2 = 1;
        Integer b2 = 1;
        System.out.println(a2 == b2);
        System.out.println(a2.equals(b2));

        /**
         *输出:false, true
         * Integer类的缓存机制
         */
        Integer a3 = 128;
        Integer b3 = 128;
        System.out.println(a3 == b3);
        System.out.println(a3.equals(b3));
常量池

常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。观察如下代码:

/**
         * 输出:false, true
         */
        Integer a1 = new Integer(1);
        Integer b1 = new Integer(1);
        System.out.println(a1 == b1);
        System.out.println(a1.equals(b1));

        /**
         *输出:true, true
         */
        Integer a2 = 1;
        Integer b2 = 1;
        System.out.println(a2 == b2);
        System.out.println(a2.equals(b2));

因为例子中的a2和b2中的1都是整型常量,它们在编译期就被确定了,所以a2 == b2为true。
用new Integer()创建的整型不是常量,不能在编译期就确定,所以new Integer()创建的整型不放入常量池中,它们有自己的地址空间。

你可能感兴趣的:(常量池与Integer类的缓存机制)