在面试中给你留的坑:Integer 缓存

不知道你在项目中有没有见过,有些同事对Integer类型的两个参数使用==号比较是否相等?

反正我见过的,那么这种用法对吗?

我的回答是看具体场景,不能说一定对,或不对。

有些状态字段,比如:orderStatus有:-1(未下单),0(已下单),1(已支付),2(已完成),3(取消),5种状态。

这时如果用==判断是否相等:

Integer orderStatus1 = new Integer(1);
Integer orderStatus2 = new Integer(1);
System.out.println(orderStatus1 == orderStatus2);

返回结果会是true吗?

答案:是false。

有些同学可能会反驳,Integer中不是有范围是:-128-127的缓存吗?

为什么是false?

先看看Integer的构造方法:
public Integer(int value) {
        this.value = value;
}

它其实并没有用到缓存。

那么缓存是在哪里用的?

答案在valueOf方法中:
public static Integer valueOf(int i) {
   if (i >= IntegerCache.low && i <= IntegerCache.high)
     return IntegerCache.cache[i + (-IntegerCache.low)];
   return new Integer(i);
}
这段代码的含义就是在Integer中维持了一个缓存IntegerCache。
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) {
                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到127,言外之意,就是当我们用方法valueOf(int i)时候,会走缓存,
可参考文章:Inetger源码分析

如果上面的判断改成这样:
String orderStatus1 = new String("1");
String orderStatus2 = new String("1");
System.out.println(Integer.valueOf(orderStatus1) == Integer.valueOf(orderStatus2));

返回结果会是true吗?

答案:还真是true。

我们要养成良好编码习惯,尽量少用==判断两个Integer类型数据是否相等,只有在上述非常特殊的场景下才相等。

而应该改成使用equals方法判断:

Integer orderStatus1 = new Integer(1);
Integer orderStatus2 = new Integer(1);
System.out.println(orderStatus1.equals(orderStatus2));

运行结果为true。

java经典面试题 文章被收录于专栏

给大家整理目前最流行的经典面试题,希望能做到问到一个面试题,你就能拿捏住,而不是全部准备而全部不会。

全部评论
学到了,感谢分享
点赞 回复 分享
发布于 2022-10-23 11:30 陕西

相关推荐

自由水:笑死了,敢这么面试不敢让别人说
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务