【Ali规约】比较相同类型的包装类对象之间值,使用 equals 方法

原因
包装类对象原本是引用对象,若使用 == 只是比较两个引用变量是否指向相同的对象。在JDK1.5之后有了自动装箱、拆箱。对于 Integer 对象来说,初始值在-128 ~ 127时会将对象放入缓存池(IntegerCache.cache),下次调用相同的值将直接复用。在该区间的Integer 对象可直接进行判读,该区间以外的对象在 Heap 上产生,不会进行复用。所以推荐使用 equals 方法进行判断。下列代码很清楚表达。

Integer a = 1;
Integer b = 1;
// 输出 ture
System.out.println(a == b);

Integer c = 123;
Integer d = 123;
// 输入 true
System.out.println(c == d);

Integer e = 129;
Integer f = 129;
// 输入 false
System.out.println(e == f);

源码
简单的知道原因还是不行,还是要看看Integer的源码。

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

发现若 i 的值在 IntegerCache.low ~ high 的范围内则返回一个缓存值。再看看 IntegerCache 的源码。

private static class IntegerCache {
    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);
                // 最大数组长度 Integer.MAX_VALUE
                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++);
                // 缓存 [-128, 127] 区间的值
                assert IntegerCache.high >= 127;
        }
        private IntegerCache() {}
    }

在 IntegerCache 源码中可以知道,只要初始化的数字在 cache[low, high]的范围内,就返回 cache 数组的数据。否则将在 Heap 上产生新的 Integer 值。JDK 中默认 IntegerCache.cache 的范围是 -128 ~ 127。 在 JVM 调优的时候通过 -XX:AutoBoxCacheMax 修改最大值。该则规约中强制使用 equals 比较所有相同类型包装类的值。因为在 JDK 中其他的包装类都有缓存机制,分别为:

  • Byte 包装类有 ByteCache 用于缓存 Byte 对象,固定范围是 -128 ~ 128 、
  • Short 包装类有 ShortCache 用于缓存 Short 对象,固定范围是 -128 ~ 128 、
  • Long 包装类有 LongCache 用于缓存 Long 对象,固定范围是 -128 ~ 128 、
  • Character 包装类有 CharacterCache 用于缓存 Character 对象,固定范围是 0 ~ 127、
  • 除了 IntegerCache 其他包装类的缓存机制均不可以改变范围。
发布了104 篇原创文章 · 获赞 264 · 访问量 54万+

猜你喜欢

转载自blog.csdn.net/teavamc/article/details/90702527