fastjson一个有趣的bug
今天下午同事找我看一个bug,看完之后觉得非常有意思,所以准备记录一下。原来的代码我就不贴了,比较复杂。我就贴一个简单的重现代码吧。
//创建jsonarray数组
JSONArray array = new JSONArray();
//第一个json对象 JSONObject
com.alibaba.fastjson.JSONObject a = new com.alibaba.fastjson.JSONObject();
a.put("name", "张三");
a.put("age", "14");
array.add(a);
//第二个json对象
com.alibaba.fastjson.JSONObject b = new com.alibaba.fastjson.JSONObject();
b.put("name", "李四");
b.put("age", "44");
array.add(b);
//第二个json对象
net.sf.json.JSONObject c = new net.sf.json.JSONObject();
c.put("name", "王五");
c.put("age", "14");
array.add(c);
//第二个json对象
net.sf.json.JSONObject d = new net.sf.json.JSONObject();
d.put("name", "王五");
d.put("age", "14");
array.add(d);
//遍历
for(int i=0;i<array.size();i++) {
//如果年龄等于14岁
if("14".equals(array.getJSONObject(i).get("age"))) {
//将14岁改成41岁
array.getJSONObject(i).put("age", "41");
}
}
//输出
for(int i=0;i<array.size();i++) {
System.out.println("name="+array.getJSONObject(i).get("name"));
System.out.println("age="+array.getJSONObject(i).get("age"));
}
你们猜猜结果是什么?下面就是输出结果,是不是和想象的不一样。后面两个王五的age并没有变!!!那为什么前面的变了呢。
name=张三
age=41
name=李四
age=44
name=王五
age=14
name=王五
age=14
带着这样的疑问我就去看源码了。下面是fastjson的源码。他的问题就出在这个 array.getJSONObject(i)获取寄送object
public JSONObject getJSONObject(int index) {
Object value = list.get(index);
if (value instanceof JSONObject) {
return (JSONObject) value;
}
//如果这里的object的类型不是com.alibaba.fastjson.JSONObject他会执行toJSON的方法,我们在进这个方法看看
return (JSONObject) toJSON(value);
}
下面是截取的一段代码。
if (javaObject == null) {
return null;
}
if (javaObject instanceof JSON) {
return javaObject;
}
if (javaObject instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) javaObject;
//这里new了一个新的jsonobject对象
JSONObject json = new JSONObject(map.size());
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
String jsonKey = TypeUtils.castToString(key);
Object jsonValue = toJSON(entry.getValue());
json.put(jsonKey, jsonValue);
}
//这里返回了这个对象
return json;
}
从上面的代码就明白了为什么下面两个人的年龄没有变了。因为他的对象不是com.alibaba.fastjson.JSONObject所以在getJSONObject给他创建了一个新的对象。然后你修改的是新的对象的值。你JSONArray里面的对象值并没有改变。所以输出还是原来的。
//创建jsonarray数组
JSONArray array = new JSONArray();
//第一个json对象 JSONObject
com.alibaba.fastjson.JSONObject a = new com.alibaba.fastjson.JSONObject();
a.put("name", "张三");
a.put("age", "14");
array.add(a);
//第二个json对象
com.alibaba.fastjson.JSONObject b = new com.alibaba.fastjson.JSONObject();
b.put("name", "李四");
b.put("age", "44");
array.add(b);
//第二个json对象
net.sf.json.JSONObject c = new net.sf.json.JSONObject();
c.put("name", "王五");
c.put("age", "14");
array.add(c);
//第二个json对象
net.sf.json.JSONObject d = new net.sf.json.JSONObject();
d.put("name", "王五");
d.put("age", "14");
array.add(d);
JSONArray array2 = new JSONArray();
//遍历
for(int i=0;i<array.size();i++) {
//如果年龄等于14岁
if("14".equals(array.getJSONObject(i).get("age"))) {
//将14岁改成41岁
array.getJSONObject(i).put("age", "41");
//用一个新的对象接住
JSONObject e = array.getJSONObject(i);
e.put("age", "41");
//添加到另一个数组
array2.add(e);
}
}
//输出
for(int i=0;i<array.size();i++) {
System.out.println("name="+array.getJSONObject(i).get("name"));
System.out.println("age="+array.getJSONObject(i).get("age"));
}
System.out.println("====================华丽的分割线=================");
//输出2
for(int i=0;i<array2.size();i++) {
System.out.println("name="+array2.getJSONObject(i).get("name"));
System.out.println("age="+array2.getJSONObject(i).get("age"));
}
在看看结果!正常了。
name=张三
age=41
name=李四
age=44
name=王五
age=14
name=王五
age=14
====================华丽的分割线=================
name=张三
age=41
name=王五
age=41
name=王五
age=41