分析

public class Test {
    public static void main(String[] args) {
        Integer a = 90;
        Integer b = 90;
        System.out.println(a==b); //true

        Integer i = 130;
        Integer j = 130;
        System.out.println(i==j); //false
    }
}

output

true
false

诡异,实则不然。

通过观察Integer的源码显示,在Integer内部,维护了一个静态内部类IntegerCache,在程序运行时,Integer就会执行该内部类里面的静态代码块,大致意思就是在该类中,创建了一个cache数组,存放了-128----127的数据,如下:

static final int low = -128;
static final int high;
static final Integer cache[];
static {
    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);
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        } catch( NumberFormatException nfe) {
        }
    }
    high = h;

    cache = new Integer[(high - low) + 1];
    int j = low;
    for(int k = 0; k < cache.length; k++)
        cache[k] = new Integer(j++);
    assert IntegerCache.high >= 127;
}

由于我们在创建Integer变量的时候,会调用Integer中的public static Integer valueOf(int i)方法,在该方法中,会进行一个简单的判断,如果创建的变量的数字是在-128----127之间,就在内部类之前创建的cache数组中去找到返回即可,但是看到内部类IntegerCache中的cache数组也是Integer类型的,所以得出在该区间内,直接是通过引用赋值的,所以也就会出现开始的a==btrue,具体的valueOf( )方法如下:

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

可以看出,如果创建的Integer变量没有在cache的范围内,就会new一个新的Integer,所以就会出现新的地址,所以才会出现一开始的i==jfalse

总结

当Integer的变量在-127----128之间的时候,可以使用==来进行比较大小,当不在这个范围的时候,==就失效了,比较的是地址,使用equals方法来比较,如果一个是int,一个是Integer的时候,可以使用==或者equals比较都可以,因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较。

public static void main(String[] args) {
    Integer a = 90;
    Integer b = 90;
    System.out.println(a == b);//true
    System.out.println(a.equals(b));//true

    Integer i = 130;
    Integer j = 130;
    System.out.println(i == j);//false
    System.out.println(i.equals(j));//true

    Integer m = 150;
    Integer n = 150;
    System.out.println(m.equals(n));//true

    int x = 100;
    Integer y = 100;
    System.out.println(x == y);//true
    System.out.println(y.equals(x));//true

}