Integer类型之间的比较

问题描述

具体如下:

Integer num1 = 10;
Integer num2 = 10;
Integer num3 = 30000;
Integer num4 = 30000;

System.out.println(num1 == num2); // True
System.out.println(num3 == num4); // False

为什么同为两个Integer对象比较,一个为真,一个为假?

分析

  1. Integerint类型的包装类,在给Integer类型赋值int值时,会通过Integer.valueOf()进行自动装箱。Integer num1 = 10;其实等价于Integer num1 = Integer.valueOf(10);。同样的,若Integer类型与int类型进行比较,在JDK1.5以上也会自动进行拆箱。

  2. 所以我们通过Integer.valueOf()入手,查看其源码:

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    

    可以发现,若传入的int值在IntegerCache.lowIntegerCache.high之间,则返回IntegerCache.cache数组中的一个对象。若超出范围,则重新创建一个Integer对象。

  3. 继续追踪IntegerCache类,发现其是定义在Integer中的一个静态内部类。其中包含一个静态代码块,用于在加载时创建cache

    static {
                // 略
    
                // Use the archived cache if it exists and is large enough
                if (archivedCache == null || size > archivedCache.length) {
                    Integer[] c = new Integer[size];
                    int j = low;
                    for(int i = 0; i < c.length; i++) {
                        c[i] = new Integer(j++);
                    }
                    archivedCache = c;
                }
                cache = archivedCache;
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    

总结

对于[-128, 127]范围内的数,会直接返回提前创建好的缓存的地址。而对于超出这个范围的数,则会重新new Integer。问题中的num1num2均为[-128, 127]内的数字,所以拿到的都是缓存中的同一个对象。进行==地址比对时自然为真。而对于num3num4,即使intValue相同,但是由于超出范围,每次装箱拿到的都是新new的一个Integer对象,进行==地址比对时就为假。

文章作者: Serendipity
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 闲人亭
杂货店 Java基础
喜欢就支持一下吧