关于Integer之间的比较躺的坑多了也就有了经验,-128~127范围能可以用equals或“==”都可以,不在范围内只能使用equals,例如:
@Test
public void test6 () {
Integer num1 = 17;
Integer num2 = 17;
Integer num3 = 177;
Integer num4 = 177;
System.out.println(num1 == num2); //true
System.out.println(num1.equals(num2)); //true
System.out.println(num3 == num4); //false
System.out.println(num3.equals(num4)); //true
}
通过测试结果发现我们的经验还是很正确的,但是我们不能满足知其然不知其所以然,这篇文章主要就是探究其所以然。
下面我们就去扒一扒Integer的源码,由于JDK 1.5之后加入了自动装箱功能( valueOf() ),所以
Integer num1 = 17 等价于 Integer num1 = Integer.valueOf(17)
我们先去看看 valueOf() 方法
咦,IntegerCache 是什么鬼?
这里有两种返回形式,由于java里面每new 一次就是在内存中开辟一块内存,所以 new 出来的对象引用地址都不一样,结合我们丰富的填坑经验return new Integer(i)返回的就应该是-128~127范围之外的数据了吧。
我们再来看看 IntegerCache 是什么鬼,下面是 IntegerCache 的源码
/**
* 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() {}
}
上面IntegerCache的源码显示,在类加载完成后会把 -128~high 放在缓存中。
结合 valueOf() 方法可以知道,在 i 在 -128~high 范围之内直接从缓存中获取对象,所以它们的引用地址是相同的。
源码注释里面说,最大边界可以通过-XX:AutoBoxCacheMax进行配置,但是不能小于127,也不会大于Integer.MAX_VALUE最大值。也就是配置 -XX:AutoBoxCacheMax 之后就不在限制于 -128~127 的范围,那样结果就和我们的经验不相符了。
这就是关于 Integer 类型比较的其所以然。