[java] Java JSON serialization - best practice

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 JSONException //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?

This question is related to java json design-patterns

The answer is


Have your tried json-io (https://github.com/jdereg/json-io)?

This library allows you to serialize / deserialize any Java object graph, including object graphs with cycles in them (e.g., A->B, B->A). It does not require your classes to implement any particular interface or inherit from any particular Java class.

In addition to serialization of Java to JSON (and JSON to Java), you can use it to format (pretty print) JSON:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

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

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()'.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to design-patterns

How to implement a simple scenario the OO way Implementing Singleton with an Enum (in Java) What is difference between MVC, MVP & MVVM design pattern in terms of coding c# Best Practices for mapping one object to another REST API Login Pattern When should we use Observer and Observable? How to implement a FSM - Finite State Machine in Java Function in JavaScript that can be called only once Thread Safe C# Singleton Pattern Repository Pattern Step by Step Explanation