int和Integer(== 和 equals的区别)
本篇文章先从一道题目开始
题目内容
    int a = 100;
    Integer b = 100;
    System.out.println(a == b); // true
    Integer a1 = 101;
    Integer b1 = 101;
    System.out.println(a1 == b1); // true
    Integer a2 = 200;
    Integer b2 = 200;
    System.out.println(a2 == b2); // false
以上的结果是否和你预期的一一致呢?如果都能正确的回答,说明对java的自动拆装箱和整数的缓存池有了一定的了解。
自动拆装箱,说的通俗易懂点就是基本类型和其包装类之间的相互转换
| 类型 | 类型转换 | 实现方法 | 
|---|---|---|
| 装箱 | int 转 Integer | Integer x = Integer.valueOf(int value) | 
| 拆箱 | Integer 转 int | int y = x.intValue() | 
关于int 和 Integer之间的比较,Integer和Integer之间的比较,先看一下比较规则
比较规则
| 类型比较 | 比较规则 | 
|---|---|
| int 和 int | == 比较的是值、无法使用equals比较 | 
| int 和 Integer | 基本类型和包装类型, 会进行自动拆箱转为基础类型进行比较 | 
| Integer 和 Integer | ==比较的是引用地址、equals比较的是值 | 
在Integer 和 Integer 比较时,使用==比较的是引用地址,那么久涉及常量池(IntegerCache)的问题,分以下两种情况
1、 是否使用常量池
 - new Integer()构造方法, 不使用缓存池
 
 - Integer.valueOf()方法, 使用缓存池
2、大小是否在IntegerCache范围内
 - 在【-128 ~127】范围内,使用缓存池
 
 - 在【-128 ~127】范围外,不使用缓存池
看一下Integer的源码可知,IntegerCache是Integer的静态内部类
当使用valueOf()创建一个Integer时,
在[IntegerCache.low,IntegerCache.hign]闭区间范围内的,使用缓存池
否则使用new Integer(i)创建一个新的对象
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
IntegerCache.low=-128; IntegerCache.high =127
那么这个缓存池的范围可以修改吗?是可以的!
不过只能设置上限,下限是固定的-128
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
        private IntegerCache() {}
    }
代码大致的内容:
读取java.lang.Integer.IntegerCache.high变量的值,如果不为空,和127比较大小Math.max(i, 127),将上限设置为两个中的最大值
然后初始化一个Integer数组,[-128, -127, -126, -125, -124,....... 124, 125, 126, 127]
其中new Integer(j++) 是先赋值,再加一
基于以上的结论和认识,尝试做一下下面的比较
示例一
    Integer a3 = new Integer(121);
    Integer b3 = new Integer(121);
    System.out.println(a3 == b3); // false
    System.out.println(a3.equals(b3)); // true
    Integer a4 = new Integer(300);
    Integer b4 = new Integer(300);
    System.out.println(a4 == b4); // false
    System.out.println(a4.equals(b4)); // true
示例一解读:
首先new Integer()构造方法, 不使用缓存池,所以无需考虑范围
==比较的是引用地址,创建了两个对象,所以是false
equals比较的是值,所以是true
很多人好奇为什么equale比较的是值,这个可以看一下Integer的源码

示例二
    Integer a5 = Integer.valueOf(122);
    Integer b5 = Integer.valueOf(122);
    System.out.println(a5 == b5); // true
    System.out.println(a5.equals(b5)); // true
    Integer a6 = Integer.valueOf(500);
    Integer b6 = Integer.valueOf(500);
    System.out.println(a6 == b6); // false
    System.out.println(a6.equals(b6)); // true
示例二解读:
Integer.valueOf()方法, 使用缓存池,使用缓存池,就需要看大小是否在IntegerCache范围内,122在缓存池范围内,500不再缓存池范围内
==比较的是引用地址,使用缓存池创建的a5和b5,实际上是同一个对象,所以是true,a6和b6的大小不再范围内,不适用缓存池,所以创建了两个对象,所以是fasle
equals比较的是值,所以是true
示例三
    Integer a7 = Integer.valueOf(133);
    Integer b7 = new Integer(133);
    System.out.println(a7 == b7); // false
    System.out.println(a7.equals(b7)); // true
示例三解读:
Integer.valueOf() 方法使用缓存池,且133在【-128 ~127】范围内,a7变量指向常量池中的133
new Integer() 构造方法不使用缓存池,b7指向堆内存中的133对象,两个对象不是同一个,所以a7 == b为false
equals比较的是值,所以是true
如果对以上的还有疑惑,重新看上面的比较规则;
                    
                
                
            
        
浙公网安备 33010602011771号