Integer
- Integer是int的包装类,int则是java的一种基本数据类型 //Integer 类在JDK1.0的时候就有了,它是一个类,是 int 基本数据类型的封装类
- Integer变量必须实例化后才能使用,而int变量不需要 //如1中,Interger为包装类而int为基本数据类型
- Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 //这一点是后续比较的铺垫
- Integer的默认值是null,int的默认值是0 //这个也是一个坑…后续我会写一片博客来探讨这个问题
出现场景
具体代码我就不贴出来的,读者能理解大概的意思就行。
Integer i = XXX;
Integer j = XXXX;
//省略一部分计算
if(i == j){
//TODO do A
}else{
//TODO do B
}
- 代码是以前别人写的,出现了一个bug就是有时候能if能判断准确,有时候又不行。经过排查也不存在别的地方的问题,bug出现原因应该就是==的判断和Integer的特殊性。
- 众所皆知,比较的时候使用==会去比较内存地址,而equals()是对值进行比较与内存地址无关。
- 但是这里使用了为什么会出现偶尔能出现判断成功有时候会判断失败呢?
JVM会自动维护八种基本类型的常量池,int常量池中初始化-128~127的范围。
所以Integer在-128~127的范围内时会从常量池中进行取值,这是JVM把一定范围的值进行一个缓存来达到自优化的方式。
也就是说Integer的范围在-128~127的时候,new出来的对象的内存地址其实是同一个,即hashCode是相等的。在进行==比较的时候,就会正确,而超过这个范围的数值的时候是指向的不同地址,自然判断失败了。
/**
* Returns a hash code for this {@code Integer}.
*
* @return a hash code value for this object, equal to the
* primitive {@code int} value represented by this
* {@code Integer} object.
*/
public int hashCode() {
return value;
}
查看源码发现Integer是重写过hashCode(),返回的是Integer的值。
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类中有一个静态内部类IntegerCache,在IntegerCache类中有一个Integer数组,用以缓存当数值范围为-128~127时的Integer对象。
后言
不过说起来,还是推荐大家比较的时候能用equals()就用equals()或者是其他更好的比较方法,用==真的不够规范容易出问题。