1、128陷阱描述
Integer 整型 -128~127 超过这个范围,==比较会不准确
例子
public static void main(String[] args) {
Integer a=128;
Integer b=128;
Integer e=127;
Integer f=127;
System.out.println(a==b); //输出false
System.out.println(a.equals(b)); //输出true
System.out.println(e==f); //输出true
System.out.println(e.equals(f)); //输出true
}
}
2、源码分析
当执行Integer a=128时,实际上会首先调用Integer.valueOf(128)来指定int值返回Integer实例给a,Integer.valueOf()源码如下:
注解翻译如下:
该方法返回一个表示指定
int
值的Integer
实例。如果不需要创建新的Integer
实例,通常应该优先使用此方法而不是Integer(int)
构造函数,因为此方法可能通过缓存经常请求的值来显著提高空间和时间性能。此方法将始终缓存范围在-128到127(包含-128和127)之间的值,并且可能还会缓存这个范围之外的其他值。参数:
i
– 一个int
类型的值。返回值:
- 一个表示
i
的Integer
实例。自版本:
- 1.5开始提供。
同时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() {}
}
此静态类定义了IntegerCache.low=-128,IntegerCache.high=127,以及cache数组,根据high和low的值计算数组长度(high - low + 1),并为每个索引位置创建一个新的Integer对象。
a:当执行Integer.valueOf(128)时,首先会判断128>=-128&&128<=127,如果是false,直接创建新的Integer并返回;
同理,执行Integer b=128时也是会new Integer(128),并返回
c:当执行Integer.valueOf(127)时,由于127属于[-128,127],因此会直接返回事先创建好的cache[127]存储的Interger对象
同理,执行Integer d=127时,也是直接引用的cache[127]存储的Interger对象
因此a,b, c,d的地址如下
可以看到,a和b的地址不一致,这是由于a和b虽然值相等,但是其值不在[-128,127]范围内,因此每次会new Integer,在堆中重新分配内存地址,但是e和f属于 [-128,127],因此每次直接使用Integer缓存的对象,其地址一样。
同时==比较的是对象的地址,因此a==b会是false;
equals比较的是对象的值,因此a==b是true;
同理,c和d不管是地址还是值都相等,因此都为true
至此,就是我对128陷阱的全部理解,欢迎指正!!