Integer和Long可以用==号比较值大小吗?

遇到问题,最好的办法是写个Test类测试一下,再看源码 

    @Test
    public void test() throws Exception {
        Integer a = 127;
        Integer b = 127;
        Integer c = new Integer(127);
        Integer d = new Integer("127");
        Integer e = new Integer("127");

        Integer x = 128;
        Integer y = 128;

        Long p = 128L;
        Long q = 128L;

        Long r = 127L;
        Long s = 127L;

        System.out.println(a==b);
        System.out.println(x==y);
        System.out.println(r==s);
        System.out.println(p==q);

        System.out.println(a==c);
        System.out.println(c==d);
        System.out.println(d==e);

    }

执行结果是,除了a,b和r,s相等外,其余都为false

"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" -ea -

true
false
true
false
false
false
false

new Integer(),new Long()与new String()一样,本质是开辟一个新的地址存储对象.

那 127组和128组为什么结果不一样呢?

当给Integer赋整数值的时候,实际是调用了java.lang.Integer#valueOf(int)方法

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)],如果不在缓存空间,再new 一个.

,所以推测是 127这组落在了缓存区间,所以ab实际上取得同一个缓存地址,128没有落在缓存区间,new了一个新地址,所以结果不一样.我们来看源码

/**    // 因为-128到127是常用的包装对象,所以在第一次使用的时候初始化并缓存到数组中
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     * // 可以通过参数-XX:AutoBoxCacheMax= 设置缓存大小
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * 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;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            // 可以通过参数java.lang.Integer.IntegerCache.high设置缓存最大值,设置时要注意
            // -XX:AutoBoxCacheMax参数是否满足
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    // 取设置参数和默认127的最大值,但是也不能超过
                    // Integer.MAX_VALUE - (-low) -1
                    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() {}
    }

静态内部类初始化的时候给缓存数组赋值,默认情况下,high为127,low是-128.

当给数组赋值a = 127时,用的是缓存cache[127+(-IntegerCache.low)]就是 cache[255],

而初始化时,cache的size是high-low+1为256,cache[255]就是数组的最后一个,即new Integer(127).

所以Integer a = 127,就是返回了缓存中的cache[255],所以每次都是返回缓存.地址相等.而128不在缓存中,就返回new Integer(128).地址不相等

Long也一样有静态缓存类LongCache,不过比起Integer更简单一些,直接设置了-128到127共256个缓存,当long类型落在缓存区间,使用==比较大小会相等.

private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

当Long r = 127L时,实际是调用了Long.valueOf()方法自动装箱,先去拿缓存,如果没有再new Long()

/**
     * Returns a {@code Long} instance representing the specified
     * {@code long} value.
     * If a new {@code Long} instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Long(long)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * Note that unlike the {@linkplain Integer#valueOf(int)
     * corresponding method} in the {@code Integer} class, this method
     * is <em>not</em> required to cache values within a particular
     * range.
     *
     * @param  l a long value.
     * @return a {@code Long} instance representing {@code l}.
     * @since  1.5
     */
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

但是,阿里巴巴开发规范手册强制要求使用equals比较,不推荐使用==比较 .

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞翔的咩咩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值