首先,看一下代码:
package example;
/**
*
* @author liuhuanchao
* email 740970978
*/
public class Test {
public static void main(String[] args) {
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println(a==b);
System.out.println(a.equals(b));
System.out.println("1------------------------->br");
Integer c=5;
Integer d=5;
System.out.println(c==d);
System.out.println(c.equals(d));
System.out.println("2------------------------->br");
Integer e=128;
Integer f=128;
System.out.println(e==f);
System.out.println(e.equals(f));
}
}
控制台输出的是:
false
true
1------------------------->br
true
true
2------------------------->br
false
true
也许大家很困惑吧,现在我来给大家分析分析,有不对的地方还请指教。
对于a,b的输出结果:
”==“比较的是栈中a和b在堆中的地址,可以看出是不同的,所以为false。
“equals”比较的是在堆中的数值,都是10,所以为true
c,d,e,f的结果分析:
IntegerCache源码
// IntegerCache,一个内部类,注意它的属性都是定义为static final
private static class IntegerCache {
static final int high; //缓存上界,暂为null
static final Integer cache[]; //缓存的整型数组
// 块,为什么定义为块
static {
final int low = -128; // 缓存下界,不可变了。只有上界可以改变
// high value may be configured by property
// h值,可以通过设置jdk的AutoBoxCacheMax参数调整(以下有解释),自动缓存区间设置为[-128,N]。注意区间的下界是固定
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
// 通过解码integerCacheHighPropValue,而得到一个候选的上界值
int i = Long.decode(integerCacheHighPropValue).intValue();
// 取较大的作为上界,但又不能大于Integer的边界MAX_VALUE
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++); // -128到high值逐一分配到缓存数组
}
private IntegerCache() {}
}
也就是说,这个数字存的值是-128-127,如果值在这个范围之内,就在缓存中去找,否则就创建对象,之后赋值.
究竟哪个范围的整型数被缓存而不需要new了呢?先了解一下什么是“自动装箱池”,再围观IntegerCache源码就清楚。
1、看API里面的注释
/**
* 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>.
*/
getAndRemoveCacheProperties方法,用于获取或移除JDK对Integer设置的缓存属性,同时也是调整jvm:AutoBoxCacheMax选项,调整“自动装箱池”的大小
/**
* 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>.
*/
getAndRemoveCacheProperties方法,用于获取或移除JDK对Integer设置的缓存属性,同时也是调整jvm:AutoBoxCacheMax选项,调整“自动装箱池”的大小
// 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
}
}