Integer与Long的缓存
先判断下下面代码的输出结果
Qa:----------------------------------------------
Long a = Long.valueOf(127);
Long b = Long.valueOf(127);
System.out.println(a == b);
Long b = Long.valueOf(127);
System.out.println(a == b);
Qb:---------------------------------------------------
Long a = Long.valueOf(128);
Long b = Long.valueOf(128);
System.out.println(a == b);
Long b = Long.valueOf(128);
System.out.println(a == b);
--------------------------------------------------------
Qa:true
Qb:false
看jdk关于Long类型的源码:
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
可以看到-128到127间的值北放到了一个数组中,即代码中的LongCache.cache[],所以我们拿到的是同一个实例,同理其它大类型也是同样,可以在看下Integer验证下
所以,项目中判断值是否相等的话,不要用==,用equals方法
public static void main(String[] args) { Integer a=1; Integer b=2; Integer c=3; Integer d=3; Integer e=127; Integer f=127; Integer e2=128; Integer f2=128; Long g=3L; System.out.println(c==d); System.out.println(e==f); System.out.println(e2==f2); System.out.println(c==(a+b)); System.out.println(c.equals(a+b)); System.out.println(g==(a+b)); System.out.println(g.equals(a+b)); }
结果是
true true false true true true false
1. java在对int型数据自动装箱为Integer对象的时候,如果值在-128-127之间,则会在内存中公用相同对象。比如前面的
Integer e=127;
Integer f=127;
中,e和f其实是引用了同一个对象。
JVM这样做的原因其实很好理解,就如同设置了字符串池一样,可能是他们通过统计发现java对int的定义很大部分都是在-128-127之间,并且通过性能分析发现装箱操作在这部分的开销占据很大一部分。
2. 包装类的“==”运算在没有遇到算术运算的时候是不会自动拆箱的。
3. Object.equals(Object obj)方法会先判断obj对象是否是该Object类型,如果不是,直接返回false;如果是则通过类型转换再进行比较其值。可以参考下面的Integer类的equals代码
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }

浙公网安备 33010602011771号