程序员码农的世界程序园

一个很多人都会答错的java基础题

2019-06-11  本文已影响35人  山东大葱哥

题目

以下代码的输出结果是什么?

public class Question {
    public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;
        Integer i5 = new Integer(100);
        Integer i6 = new Integer(100);

        System.out.println(i1 == i2);//输出什么?
        System.out.println(i3 == i4);//输出什么?
        System.out.println(i5 == i6);//输出什么?
    }
}

答案

也许有些朋友会说都会输出false,或者也有朋友会说都会输出true。但是事实上输出结果是:

true
false
false

分析

原因分析:
想要分析原因我们需要从自动装箱代码着手,也就是Integer.valueOf()方法

    public static Integer valueOf(int i) {
        //如果i大于等于-128,小于等于127(一般情况下IntegerCache.high为127),则从整数缓存中获取
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        //如果不在以上范围则,new一个新的整数对象
        return new Integer(i);
    }

从以上代码我们可以看出对于i1i2是从整数缓存中获取的同一个对象,所以==返回true,而对于i3i4则是new的新对象,所以==返回false,而i5i6都是直接new的新对象,所以==返回false。

至于为什么说是一般情况下IntegerCache.high为127呢?这就需要看一下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);
                    //如果配置的值小于127,则默认127,如果大于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 = 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() {}
    }

可以看到配置文件是通过配置文件读取的值,默认情况下为127,但我们可以通过修改配置的方式改变这个值,但只有配置的值大于127时才能生效,小于127时会默认为127。

反虐面试官

修改方式为增加启动参数-Djava.lang.Integer.IntegerCache.high=350
在idea中如下图所示:

image.png

经过配置后输出结果就会发生变化:

true
true
false

理解了原理就可以在面试时反虐一下面试官,明确告诉面试官这个题目的输出结果不固定,对于i1==i2肯定为true,而i3==i4则可能为true也可能为false,这取决于配置参数。

上一篇 下一篇

猜你喜欢

热点阅读