栈与堆几个经典的例子

先看看代码呗

public static void main(String args[])   
    {   
    	   /*
    	   * "==" 对包装类型是进行 的地址比较。i1和i2为引用类型存放在栈区,
    	   * new Integer(13) 存放在堆区,并在堆区生成了2份。
    	   * 因此i1和i2指向了堆区不同的地址。
    	   * 
    	   */
            Integer i1=new Integer(13);   
	    Integer i2=new Integer(13);   
	    System.out.println(i1==i2);//false
	    
	    /*
	     * "==" 对基本类型是进行 的值比较。
	     */
	    int i3 = 1150;
	    int i4 = 1150;
	    
	    System.out.println(i3==i4);//true
	    
	    /*
	     * In one word,拆箱之后,值比较。
	     */
	    int i5=13;   
	    System.out.println(i2==i5);//true 
	    System.out.println(i5==i1);//true
	    
	    /*
	     * 范围在-128 到 127之间为true, 反之为false。 这里有一个自动装箱的过程,
	     * 在装箱的过程中对范围在-128 到 127之间的数据进行的了缓存。
	     */
	    Integer i6 = 12;
	    Integer i7 = 12;
	    System.out.println(i6==i7);//true
	    i6 = 200; 
	    i7 = 200;
	    System.out.println(i6==i7);//false
	    	    	    
    }   


第一个问题应该很好理解,i1和i2是包装类型的引用,存放在栈区,new Integer(13)生成了两份,存在于堆区。i1和i2指向了堆内存中不同的地址,所以

 System.out.println(i1==i2);//false
第二个问题,哇哦,这种基本的都拿出来,其实第二个问题主要是为了和第一个问题做比较。“==”在包装类型之间是 地址比较, “==”在基本类型之间是 值比较

第三个问题,哎呀,这问题曾经着实让我纠结了很久。以前是这样子想的,因为 i5 是基本类型int的变量,所以i5是存放在栈内存中的,13这个数值也是存放在栈内存中的,i5 指向 13。可以这么理解吧,而引用变量i2指向的是堆内存中13这个integer对象,既然在i2和i3指向的内存地址不同,为什么“System.out.println(i2==i5)” 的结果为 true?

当时是不是脑子不转了,一句话 拆箱之后,值比较。其他就不要想了。

第四个问题看着挺有意思的,都是Integer类型,为什么这里存在一个范围呢?挺诡异的吧。 其实看看源码就知道了。这里java在对装箱过程处理的时候,对-128到127之间的数值进行了一个缓存,我猜测,应该是这些数值比较常用,而且在处理的时候效率应该更高一些。

    /**
     * Cache to support the object identity semantics of autoboxing for values between 
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage. During VM initialization the
     * getAndRemoveCacheProperties method may be used to get and remove any system
     * properites that configure the cache size. At this time, the size of the
     * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
     */

    // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
    private static String integerCacheHighPropValue;

    static void getAndRemoveCacheProperties() {
        if (!sun.misc.VM.isBooted()) {
            Properties props = System.getProperties();
            integerCacheHighPropValue =
                (String)props.remove("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null)
                System.setProperties(props);  // remove from system props
        }
    }

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

    /**
     * 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);
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值