项目上线有些天了,今天接到客户一个电话,说我们的软件有问题,我到现场看了一下,最终定位到下面的代码行:
if (customerid!=order.getCustomerId()) {
resultMap.put("resultStatus", "-1");
return resultMap;
}
此处是判断当前用户和订单的下单人是否是一个人,如果不是一个人修改状态返回。
最开始看到这个问题,想到的是订单表中的id没有插入或者插入错误,查看了数据库没有错误。并且打印了customerid和order.getCustomerId()都是137。之后想到查看一下customerid和order里面的customerid的类型,一看是Integer,这下就明白了,这个比较的是地址,于是把程序改成customerid.equals(order.getCustomerId())就解决了。
说到这里,这个bug是解决了。但回过头来想了想,为什么之前没发生这样的问题呢?
后来查阅了资料得到了结果,在java5的时候,增加了自动装箱功能,自动装箱参考如下代码:
Integer intc = 127; //真实代码 Integer intc = new Integer(127) 这样声明的变量不会自动装箱。
Integer intc = Integer.valueOf(127); //自动装箱 java虚拟机会把上面的代码解释成这样
下面我们来看valueOf实现的源码
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在-128~127之间的数 (最大值 127 可以通过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改),会返回缓存里面的值(-128到127之前的数字是经常用到的,jdk为了节省内存和提高性能把这部分值缓存了起来)。
通过上面的分析,也解决了上面提出的“为什么之前没发生这样的问题呢?”。因为之前的用户customerid还没有到达127这个数值,随着用户逐渐增加,超过了127这个数值,问题就显现出来了。