阿里巴巴的开源工具包FastJSON在处理JSON数据的时候非常好用,然而我最近实习中使用的时候发现了一处非常容易中招的陷阱:拷贝问题。举例来说:
- 比如我先有一个Json对象a是这样的
JSONObject a = new JSONObject();
a.put("key1","value1");
- 然后我需要一个跟a的值一样的新的JSON对象,发现可以直接new
JSONObject b = new JSONObject(a);
- 然后修改a中的值,发现b的也变了
a.put("key1","value2");
System.out.println(b.getString("key1");
//output : value2
翻阅源码发现,JSONObject是实现了Map接口,里面又有一个存放数据的成员变量map;于是我的new语句是这样实现的:
public JSONObject(Map<String, Object> map){
this.map = map;
}
这只是把原来对象a的map引用传给了b,两个JSON对象的map是一个东西。
那么,如何实现我想要的结果呢?对了,就是克隆。
JSONObject类实现了cloneable接口的clone方法:
@Override
public Object clone() {
return new JSONObject(new HashMap<String, Object>(map));
}
可以看出来这里确实是new了一个新HashMap,然后用它new了一个新的JSONObject给我们。所以正确写法:
JSONObject b = (JSONObject)a.clone();
多说一句,HashMap内部容器是数组,这里new HashMap(map)是新建一个HashMap,然后将map中的键值对放到了自己的数组中。