Integer类为什么大于127不相等

Integer类为什么大于127不相等

首先我们先来看一段示例代码

Integer a = 10;
Integer b = 10;
//true
System.out.println(a==b);
Integer c = 128;
Integer d = 128;
//false
System.out.println(c == d);
int e = 10;
//true
System.out.println(a == e);
int f = 128;
//true
System.out.println(f == c);
Integer g = new Integer(10);
Integer h = new Integer(10);
//false
System.out.println(g == h);

运行结果如下:

true
false
true
true
false

我们都熟悉Integer类型的取值范围是-231~231-1。a=b为true很容易理解,但是c=b估计不熟悉的人就很疑惑了,为什么都是128为什么为false呢。
如果你会去翻Integer类的源代码,你会发现创建一个新的Integer类时传入的是一个Int类型的参数。

@Deprecated(since="9")
public Integer(int value) {
    this.value = value;
}

看到这里就可以想到Integer类的有关装箱的属性了,其实当我们创建一个Integer对象时Integer a = 1000;通过反编译查看其实是下面这段代码,这就是Integer类的自动装箱。但是Integer a = 10反编译后却没有变化,因为Integer默认最大值是127。超过最大值才会进行装箱。
Integer a = Integer.valueOf(int a);
当c和d比较时对象不一致结果为false。而a和b实际比较的是同一个int对象。a和e比较的结果也可以论证这一点。可能大家这里会有些疑惑,所以这里细讲一下。首先Integer是一个类,当赋值取值在-128~127时是不会新建对象的,会从缓存中获取对象。来看一下代码应该很容易理解。

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 = 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() {}
}

当数值为128时会新建一个对象并且扩容,那么为什么是-128~127呢,

@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
这个是寻址公式:IntegerCache.cache[i + (-IntegerCache.low)]

当我们对其debug一下会发现很巧妙的事情,当i=-128就是0,127就是256。至于寻址公式怎么来的,那你就得问Java官方了。返回的是内存中的缓存对象,超出则新建。所以c和d结果为false,f和c值的比较和g和h对象的比较就不多介绍了。
总结:
到了这里就容易理解:为当Integer的值为[-128,127]时,用= =判断两个值相等的Integer可以得到true,而超出这个范围后,用= =判断两个值相等的Integer却得到false?因为当值在[-128,127]之间时, valueOf 方法不会创建新的Integer对象,而是返回从缓存中的对象,这样一来,值相同的int,下标一样,就会获取到同一个Integer对象。而超出这个范围就每次都new一个新的Integer对象,两个不同的对象的内存地址不同,用==自然会得到false。

你可能感兴趣的:(java,1024程序员节)