Integer 值比较
-128 == -128
吗?
之前一直没有注意到 Integer 类型的判断问题,我认为 “在数值判断中,== 和 equal 的效果是相同的”,直到今天写题发现包装类下的“不能”使用 == 进行判断。
Integer 是 int 的包装类,将基本类型赋值给包装类,会进行自动装箱,自动装箱操作就是进行 valueOf(int arg1)
一般 new 创建的 Integer 会在堆中。也正是因为是包装类,所以便不再是简单的基础数据类型。
我们都知道,对于 int 进行比较,使用 ==
即可判断。但是当对 Integer 类型进行判断时候,便不再是简单的数值比较了,而是对于对象间地址的比较,当生成的值处于 -128 <= value <= 127(默认)
,底层会直接从其缓存IntegerCache
中取出以提高效率,在这时候 ==
是可以匹配的。
Integer 内部缓存类 IntegerCache 实现源码
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() {}
}
但是当超出这个范围进行创建时,两对象之间则又有了不同的地址,也就无法再使用 ==
进行比较了。这个时候我们需要使用包装类的 equals 方法进行判断。
Integer 对于 Object 的 equals
方法进行了二次封装,对于该方法,官方给出的解释如下:
public boolean equals(Object obj)
> Compares this object to the specified object. The result is true if and only if the argument is not null and is an Integer object that contains the same int value as this object.
翻译过来就是:将此对象与指定的对象进行比较。 其结果是 true
当且仅当该参数(及 obj)不是 null
并且是 Integer
对象包含有相同 的int
值。
内部重写的源码是这个样子的:
public boolean equals(Object obj){
if(obj instanceof Integer){
return value == ((Integer)obj).intValue(); // 拆箱操作
}
return false;
}
其中又调用了 intValue
方法,该方法的实现是这样的:
public int intValue()
{
return value;
}
在使用 equals 比较的过程中,会先使用 instanceof
对传入的数据类型进行判断,如果类型不匹配,会直接返回 false
,当类型相同时,则会再调用 inValue()
方法进行拆箱,转化为基本数据类型 int
后与当前对象的值 value
进行比较。
此时参与比较的会变成两个 int 类型的值,而非是 Integer 类型的对象,从而可以得到我们想要的值比较结果。
小结
其实简单些记忆的话,可以记作 ==比较的是地址,equals 比较的是值。BTW:对于包装类与基本类型,我们在日常使用中还是要注意他们之间涉及到的一些装箱和拆箱的操作的。