自动装箱的陷进

<pre name="code" class="java">Integer a=1;

public static void main(String[] args) {Integer a=1;Integer b=2;Integer c=3;Integer d=3;Integer e=321;Integer f=321;Long g=3L;System.out.println(c==d);System.out.println(e==f);System.out.println(c==(a+b));System.out.println(c.equals(a+b));System.out.println(g==(a+b));System.out.println(g.equals(a+b));}
 

第一条输出和第二条输出,可能有的人会认为都是true,但是输出结果是


为什么会這样子呢,我们从Integer的源码角度分析。在分析之前,希望读者可以明白,

Integer a=1;
其实在我们写這一句之前,就已经设计到一个java为我们做好的事了, 自动装箱

Integer a=Integer.valueOf(1);
原来的代码应该是這样子,想了解“自动装箱”、“自动拆箱”、“遍历循环”这些语法糖可以去百度or谷歌,好的,现在让我们回到问题的本质,为什么会输出false呢(第二条)。

/** 
     * Returns a <tt>Integer</tt> instance representing the specified 
     * <tt>int</tt> value. 
     * If a new <tt>Integer</tt> instance is not required, this method 
     * should generally be used in preference to the constructor 
     * {@link #Integer(int)}, as this method is likely to yield 
     * significantly better space and time performance by caching 
     * frequently requested values. 
     * 
     * @param  i an <code>int</code> value. 
     * @return a <tt>Integer</tt> instance representing <tt>i</tt>. 
     * @since  1.5 
     */  
    public static Integer valueOf(int i) {  
        if(i >= -128 && i <= IntegerCache.high)  
            return IntegerCache.cache[i + 128];  
        else  
            return new Integer(i);  
    } 
从Integer的valueOf反法中,我们可以看出,当i小于一个范围的时候,执行if的下一个操作,超出则会新建else的return语句,细心的读者应该想到了,321肯定超出了那个范围,是的,所以对于两个都是新建的Integer实例,自然地址不一样,因为 ==运算是判断两个对象的地址是否相等或者判断两个基础数据类型的值是否相等,而Integer不是基础数据类型,基础数据类型是:字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。那么为什么第一个输出语句为true呢,事不宜迟,让我们来看一下IntegerCache方法
private static class IntegerCache {  
        static final int high;  
        static final Integer cache[];  
  
        static {  
            final int low = -128;  
  
            // high value may be configured by property  
            int h = 127;  
            if (integerCacheHighPropValue != null) {  
                // Use Long.decode here to avoid invoking methods that  
                // require Integer's autoboxing cache to be initialized  
                int i = Long.decode(integerCacheHighPropValue).intValue();  
                i = Math.max(i, 127);  
                // Maximum array size is Integer.MAX_VALUE  
                h = Math.min(i, Integer.MAX_VALUE - -low);  
            }  
            high = h;  
  
            cache = new Integer[(high - low) + 1];  
            int j = low;  
            for(int k = 0; k < cache.length; k++)  
                cache[k] = new Integer(j++);  
        }  
  
        private IntegerCache() {}  
    }  
可以看到,里面定义了一个静态的cache数组,意味着不超出的数据Integer 3在一个静态的对象,所以c==d都是同一个静态对象,所以为true。以上就是个人的一点看法,如有不对,希望批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值