Java JSON序列化 - 最佳实践

时间:2011-09-24 15:28:35

标签: java json design-patterns

我需要为某些对象实现JSON序列化,并且在与泛型集合集成时遇到了问题。

所有可序列化的类都实现了这个接口(JSONObject来自this库):

interface JSONSerializable{
    public JSONObject dump() throws JSONException //serializes object
    public void load(JSONObject obj) throws JSONException //deserializes object
}

基于java.util.list的我的集合代码看起来或多或少像这样:

class AwesomeList<T extends JSONSerializable> implements JSONSerializable{
    private LinkedList<T> items = new LinkedList<T>();
    ...
    ...

    public JSONObject dump() throws JSONException {
        JSONObject result = new JSONObject();
        JSONArray a = new JSONArray();
        for(T i : items){
            a.put(i.dump());
        }
        result.put("items", a);
        return result;
    }

    public void load(JSONObject obj) throws JSONException{
        //here is my problem
    }
}

我的问题是:当我从JSONObject加载AwesomeList时,我需要创建它的元素,但这是不可能的,因为java禁止我写

T newItem = new T();
newItem.load(obj);

我应该如何修改此方法?

4 个答案:

答案 0 :(得分:33)

你被绑在这个图书馆吗? Google Gson很受欢迎。我本人并没有将它与Generics一起使用,但是他们的头版说Gson认为对泛型的支持非常重要。

答案 1 :(得分:4)

正如其他人暗示的那样,你应该考虑转储org.json的库。它现在已经过时了,试图解决它的问题是浪费时间。

但针对具体问题;类型变量T只是没有任何信息可以帮助您,因为它只是编译时信息。 相反,你需要传递实际的类(作为'Class cls'参数),然后你可以用'cls.newInstance()'创建一个实例。

答案 2 :(得分:1)

你试过json-io(https://github.com/jdereg/json-io)吗?

此库允许您序列化/反序列化任何Java对象图,包括其中包含周期的对象图(例如,A-> B,B-> A)。它不要求您的类实现任何特定的接口或从任何特定的Java类继承。

除了将Java序列化为JSON(以及JSON到Java)之外,您还可以使用它来格式化(漂亮打印)JSON:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

答案 3 :(得分:0)

好吧,当把它写到文件中时,你确实知道T是什么类,所以你可以将它存储在dump中。然后,当重新读回来时,您可以使用反射动态调用它。

public JSONObject dump() throws JSONException {
    JSONObject result = new JSONObject();
    JSONArray a = new JSONArray();
    for(T i : items){
        a.put(i.dump());
        // inside this i.dump(), store "class-name"
    }
    result.put("items", a);
    return result;
}

public void load(JSONObject obj) throws JSONException {
    JSONArray arrayItems = obj.getJSONArray("items");
    for (int i = 0; i < arrayItems.length(); i++) {
        JSONObject item = arrayItems.getJSONObject(i);
        String className = item.getString("class-name");
        try {
            Class<?> clazzy = Class.forName(className);
            T newItem = (T) clazzy.newInstance();
            newItem.load(obj);
            items.add(newItem);
        } catch (InstantiationException e) {
            // whatever
        } catch (IllegalAccessException e) {
            // whatever
        } catch (ClassNotFoundException e) {
            // whatever
        }
    }