其实这个问题也是在Java基础面试常常遇到的一个问题,以前没注意过,直到遇到bug,顺便记下来吧。
做客户端“忘记密码”功能有一个bug,今天调试时,发现了原因:
功能模块中有一段:
if(userpo.getId() != Long.valueOf(uid)){
throw new VerifyException("mobile have been binded for uid=" + uid ,
AppCode.VERIFY_MOBILE_IS_BIND);
}
问题就出在两个Long型对象的比较。其实即使是Java初学者,学习过对象比较,也应该知道要用equals方法,额...这个错误确实比较低级。
疑问:当初代码肯定是通过测试的,那当初是为什么会通过测试?带着疑问,查了一些资料。结论是Integer和Long内部实现是有缓存的。
例如我写了一个测试类测试Integer和Long类型对象的比较:
public class Test {
public static void main(String[] args) {
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println("a==b:" + (a==b)); //很明显false
Integer c = 129;
Integer d = 129;
System.out.println("c==d:" + (c==d)); //false
Integer e = 127;
Integer f = 127;
System.out.println("e==f:" + (e==f));//true
Long h = 128L;
Long g = 128L;
System.out.println("h==g:" + (h==g));//false
System.out.println("h.equals(g):" + h.equals(g));//true
System.out.println("h.compareTo(g):" + h.compareTo(g));// 0
Long k = 127L;
Long m = 127L;
System.out.println("k==m:" + (k==m));//true
System.out.println("k.equals(m):" + k.equals(m));//true
System.out.println("k.compareTo(m):" + k.compareTo(m));// 0
}
}
a==b:false
c==d:false
e==f:true
h==g:false
h.equals(g):true
h.compareTo(g):0
k==m:true
k.equals(m):true
k.compareTo(m):0
查看Integer源代码后发现Integer有个内部类IntegerCache,它维护了一个Integer数组cache[] ,长度为256,还有一个静态块
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
很明显这个静态块已经默认认创建出了-128~127 的 Integer 数据。 Integer在创建对象时,若值在(-128到127)范围内,则直接从缓冲区中取,若超过该范围则创建新对象,所以在-128到127范围内Integer对象值相同时,对象 == 返回true
Long对象同理。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于