看代码:

public void testInteger()
{
    Integer a = 1;
    Integer b = 1;
    Integer c = 128;
    Integer d = 128;
    System.out.println(a == b);
    System.out.println(c == d);
}

结果是什么?

 

 

 

 

答案是

true

false

这里先明确一个概念,对象之间的直等(==)比较的是两个内存的地址。而boolean byte char short int long float double八大基础类型比较的是值,即true==false,3==6这样比较的。

那么,int的包装类型Integer对象为什么有的相等,有的不相等?

且看Integer.java源码是怎么写的

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

当我们采用Integer a = 5;这样的赋值方式的时候,编译器会使用Integer中的valueOf方法自动装箱。

看上边代码第三行,数值i会与IntegerCache.low和IntegerCache.high进行比较。如果在这两个值之间,则返回一个已经存在的对象。

那么,我们顺着这条路走下去

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) {
        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);
    }
    high = h;

    cache = new Integer[(high - low) + 1];
    int j = low;
    for(int k = 0; k &lt; cache.length; k++)
        cache[k] = new Integer(j++);
}

private IntegerCache() {}
}

Integer类中包含了一个内部类,这个内部类定义了low和high ,看最下边。

cache是一个Integer数组,包含了-128到大于127的int的包装对象。

也就是说,对象之间比较的确是内存的比较,只不过这里有一个坑,Integer保留了一个小范围空间的缓存对象数组,这样如果在小范围的使用Integr对象,就不需要频繁的开辟内存。

Boolean类默认也保存了true和false对象数组。

Byte256个对象全部保存

Short和Long范围和Integer范围相同。

坑:

在进行包含<,>的比较中,基本类型的包装对象会自动进行拆箱。

在switch语句中,包装对象也会进行自动拆箱,所以不会出现大数值比较不同的情况

String类型在switch语句中经过编译后会通过equals方法实现,所以也不会出现两个相同的字符串不相等的情况。

标签: java, Java编程思想, Integer, cache

添加新评论