两个数值相等的 Integer 不一定相等

问题:

a 和 b 相等吗?

Integer a = 128;
Integer b = 128;
System.out.println("a==b -> " + (a == b));

答案:

a 和 b 不相等
a 和 b 不相等
准确来说大小关系不确定,与 VM 的配置(sun.misc.VM)有关

正式开始

一、== 的含义

==:对比的是内存地址

二、装箱和拆箱

Integer m = 128;//自动装箱,调用 valueOf() 方法
int n = m;//自动拆箱,调用 intValue() 方法

_
1. 装箱:把值类型转换成引用类型

/**
 * Returns an {@code Integer} instance representing the specified
 * {@code int} value.  If a new {@code Integer} instance is not
 * required, this method should generally be used in preference to
 * the constructor {@link #Integer(int)}, as this method is likely
 * to yield significantly better space and time performance by
 * caching frequently requested values.
 *
 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.
 *
 * @param  i an {@code int} value.
 * @return an {@code Integer} instance representing {@code i}.
 * @since  1.5
/**
 * 该方法通常应该优先于构造函数使用,因为该方法可能通过缓存频繁请求的值来获得更好的空间和时间性能
 * 此方法将始终在范围为 -128 至 127 的范围内缓存值,并且可以缓存在该范围之外的其他值
 */
public static Integer valueOf(int i) {
    //IntegerCache:见参考一
    //在 -128 ~ 127 的数
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        //直接从缓冲数组中获取
        return IntegerCache.cache[i + (-IntegerCache.low)];
    //不在 -128 ~ 127 的数,创建一个新的 Integer 对象
    return new Integer(i);
}

_
2. 拆箱:把引用类型转换成值类型

public int intValue() {
    return value;
}

参考一:IntegerCache

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
 * IntegerCache.high 可以通过 sun.misc.VM 配置进行修改
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */
private static class IntegerCache {
    static final int low = -128;
    //IntegerCache 缓存的最大值可以通过 sun.misc.VM 配置进行修改
    static final int high;
    static final Integer cache[];

    static {
        //hight 可以通过属性进行配置
        // 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 {
                //读取配置中的 high 值
                int i = parseInt(integerCacheHighPropValue);
                //最大值不小于 127
                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
        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() {}
    }
  1. 缓存数组 IntegerCache 的最大值 high 是可以修改的,修改 sun.misc.VM.getSavedProperty 属性值即可,hight 的最小值为 127

总结:

所以,若有两个数值相等的 Integer a 和 Integer b,它们的大小关系:

范围 大小
(- ∞, -128) a != b
[-128, high] high < a 或 b,a != b;high >= a 或 b,a == b
(high, +∞) high < a 或 b,a != b;high >= a 或 b,a == b

举个栗子,int a = 128,b = 128
high 默认为 127,则 Integer:a != b;
修改 high = 128(大于 a、b 即可),则 Integer:a == b

猜你喜欢

转载自blog.csdn.net/qq_21586317/article/details/80362679