开发者

Java JSON serialization - best practice

开发者 https://www.devze.com 2023-04-07 12:22 出处:网络
I need to implement JSON serialization for some objects, and I\'ve encountered a problem when it came to integration with generic collections.

I need to implement JSON serialization for some objects, and I've encountered a problem when it came to integration with generic collections.

All serializable classes implement this interface (JSONObject comes from this library):

interface JSONSerializable{
    public JSONObject dump() throws JSONException //serializes object
    public void load(JSONObject obj) throws JSONExcept开发者_运维技巧ion //deserializes object
}

Code for my collection based on java.util.list looks more or less like this:

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
    }
}

My problem is: When I load AwesomeList from JSONObject, I need to create its elements but it's impossible since java forbids me to write

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

How should I modify my approach to this task?


Are you tied to this library? Google Gson is very popular. I have myself not used it with Generics but their front page says Gson considers support for Generics very important.


As others have hinted, you should consider dumping org.json's library. It's pretty much obsolete these days, and trying to work around its problems is waste of time.

But to specific question; type variable T just does not have any information to help you, as it is little more than compile-time information. Instead you need to pass actual class (as 'Class cls' argument), and you can then create an instance with 'cls.newInstance()'.


Well, when writing it out to file, you do know what class T is, so you can store that in dump. Then, when reading it back in, you can dynamically call it using reflection.

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
        }
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号