关于Integer类型的自动装箱与拆箱的情况
- 今天面试又被问到关于Integer的自动装箱和拆箱的问题,我回去整理了一下
public class Test {
public static void main(String[] args) {
Integer a = 100;
Integer a1 = 100;
Integer b = 200;
Integer b1 = 200;
Integer c = 10;
int c1 = 10;
Integer d = new Integer(7);
Integer d1 = new Integer(7);
System.out.println(a == a1);
System.out.println(b == b1);
System.out.println(c == c1);
System.out.println(d == d1);
}
}
- 运行结果为:
- 这是为什么呢,在java中 == 操作如果是基本类型,会在常量池中取出值判断是否相等,对于对象则判断其引用指向的地址是不是相同。如果相同,则这两个对象相等。但是第一组和第二组为什么一个是true一个是false呢?,第三组的写法是java1.5引入的自动装箱,java会帮我们把基本类型变成对象,第四组的话是比较二个对象的地址所以返回false;
- 查看底层源码我了解到
/**
* 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. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
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源码内部有一个内部类,他是Integer的缓存类。它里面有一个静态代快,在Integer类第一次加载时,就会执行它里面的代码了。
Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
可以看到,里面规定了最小的数是-128而最大的数127。所以如果是自动装箱的话,java会把这些-128到127的数的对象的引用指向之前在静态代码块里创建好的这些对象。这样在比较时虽然是对象比较地址,但是-128到127之间只要大小相同,指向的地址也相同。而这些数字之外的其他数字即使大小相同在创建时也会每次都给它创建一个新的对象。这样他们的地址不同,比较时自然不同。