美文网首页
站在源码角度看Integer相关的面试题

站在源码角度看Integer相关的面试题

作者: 蜗牛没吃饱 | 来源:发表于2020-01-01 16:08 被阅读0次

最近市场行情不太好,为了让自己保值,打算从基础开始重新学一遍java相关的知识。
今天先从最简单的Integer说起,Integer实际上是int的封装类,因为在java的世界里,万物皆对象,即便是基础数据类型,实际上在背后都会有对应的封装类。

当我们写Integer a=new Integer(100);时实际上就是纯粹的创建了一个Integer对象。
当我们写Integer a=100;时,实际上由于java语法糖的存在,编译器会将这行代码翻译成Integer a=Integer.valueOf(100);我们再来看Integer.valueOf(int i)方法:

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

继续看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() {}
}

通过以上代码,我们可以很清楚的知道在Integer内部存在一个缓存,这个缓存会默认保存-128~127个Integer对象,而且这些对象的创建写在了static块中,意味着很早就被创建出来了。一旦我们执行Integer a=x(-128<=x<=127,实际上返回的都是同一个IntegerCache中缓存的对象。只有当x>127或x<-128时,才相当于new了一个新对象。
看到这里我们就需要掌握一个技巧了:
能用a=100就不要用a=new Integer(100),以达到利用Integer缓存的机制。

Integer类还有个需要看的地方是他重写了equals方法:

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

很清晰的可以看到,Integer之间的equals比较实际上就是”值“比较,只需要看两个数一不一样就好了。那有人会问,int属于Integer嘛?当然,int在底层会被自动转成Integer,还记得那句话么?万物皆对象。

通过以上的了解,大家可以试着做一下下面这些题:

   //第1题
    int a=100;
    Integer b=100;
    System.out.print(a==b);

答案:true
解释:当一个Integer对象和基本数据类类型int相比较的时候,虚拟机会将Integer对象自动拆包成int,这个时候通过==进行比较的就是”值“了。

   //第2题
    int a=100;
    Integer b=new Integer(100);
    System.out.print(a==b);

答案:true
解释:与第一题一样,无论这个Integer对象是通过语法糖创建的,还是通过new对象创建的。其本质都已经是Integer对象了。只要是Integer对象,在和int进行==比较时,就都是”值“比较。

   //第3题
    Integer a=100;
    Integer b=100;
    System.out.print(a==b);

答案:true
解释:两个都是对象,但由于-128<100<127,所以实际上都是去的IntegerCache中的同一个对象,当两个对象进行==比较时,实际上是比较的内存地址,因为只是同一个对象的两个不同引用,所以内存地址实际相等。

   //第4题
    Integer a=130;
    Integer b=130;
    System.out.print(a==b);

答案:false
解释:IntegerCache只缓存-128-127之间的数对象。对于不在其范围内的对象都相当于创建了一个新对象。(除非动了虚拟机参数,将IntegerCache的缓存范围修改了。)

   //第5题
    int a=130;
    Integer b=130;
    Integer c=130;
    Integer d=new Integer(130);
    System.out.print(b.equal(a)&&b.equals(c)&&b.equals(d)&&c.equals(d));

答案:true
解释:integer重写了equals方法,将判断改成了值判断,值相等则equals方法一定为true。

相关文章

网友评论

      本文标题:站在源码角度看Integer相关的面试题

      本文链接:https://www.haomeiwen.com/subject/nizwoctx.html