今天在抖音上看到一条解释 【==】和【equals】区别的视频,没有用基本类型举例,而使用了包装类,可能是想顺势解释一下自动解封装,但是得出的结果却不够严谨,大致示例代码如下:
public void test1(){
Integer a = 666;
Integer b = 666;
if (a == b){
System.out.println(true);
}else {
System.out.println(false);
}
}
这个结果是多少呢?当然是false,因为他们属于不同的内存地址
那如果把a、b都换成1呢?具体代码如下:
public void test1(){
Integer a = 1;
Integer b = 1;
if (a == b){
System.out.println(true);
}else {
System.out.println(false);
}
}
结果输出了true,因为他们属于同一块内存地址。
是什么造成了这种差异呢?查看源码我们发现,装箱时调用valueOf方法,如果装箱值处于Integer缓存中时,直接从缓存中取,否则直接返回新的Integer。这就是造成差异的原因。
public static Integer valueOf(int i) {
// 如果装箱值处于Integer缓存中时,直接从缓存中取
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
// 否则直接返回新的Integer
return new Integer(i);
}
通过以下源码可知,IntegerCache的范围在 [-128, 127]之间。
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() {}
}
后记:在这个知识大爆炸的年代,虽然知识的获取变得廉价且简单了,但是并不是所有的知识都是正确的,甚至有很多为了流量的快餐知识,从根本上就是错的,作为一个程序猿要懂得知其所以然,最好能自己动一动手。