您的位置:首页 > 运维架构

栈与堆几个经典的例子

2012-01-09 10:54 232 查看
先看看代码呗

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息