Ответ 1
Вы привязаны к этой библиотеке? Google Gson очень популярен. Я сам не использовал его с Generics, но их первая страница говорит, что Gson считает, что поддержка Generics очень важна.
Мне нужно реализовать сериализацию JSON для некоторых объектов, и я столкнулся с проблемой, когда дело дошло до интеграции с коллекциями generic.
Все сериализуемые классы реализуют этот интерфейс (JSONObject исходит из этой библиотеки):
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
}
}
Моя проблема: когда я загружаю AwesomeList из JSONObject, мне нужно создать его элементы, но это невозможно, поскольку java запрещает мне писать
T newItem = new T();
newItem.load(obj);
Как мне изменить свой подход к этой задаче?
Вы привязаны к этой библиотеке? Google Gson очень популярен. Я сам не использовал его с Generics, но их первая страница говорит, что Gson считает, что поддержка Generics очень важна.
Как намекают другие, вы должны подумать о демпинге библиотеки org.json. Это в значительной степени устарело в наши дни, и попытка обойти его проблемы - пустая трата времени.
Но к конкретному вопросу; тип переменной T просто не имеет никакой информации, которая вам поможет, так как это немного больше, чем информация времени компиляции. Вместо этого вам нужно передать фактический класс (как аргумент класса cls), и затем вы можете создать экземпляр с 'cls.newInstance()'.
Хотя вы решили использовать Gson (хорошее решение).
Вот быстрый фрагмент для u для проблемы с ur
public void load(JSONObject result) throws JSONException{
JSONArray a = (JSONArray) result.get("items");
for (int i = 0; i < a.length(); i++) {
T t = (T)a.get(i);
items.add(t);
}
}
Я не тестировал его, но он должен работать, я считаю.
Ну, когда вы записываете файл в файл, вы знаете, что такое класс 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
}
}
Попробуйте json-io (https://github.com/jdereg/json-io)?
Эта библиотека позволяет сериализовать/десериализовать любой графический объект Java, включая графические объекты с циклами в них (например, A- > B, B- > A). Это не требует, чтобы ваши классы реализовали какой-либо конкретный интерфейс или наследовали какой-либо конкретный Java-класс.
В дополнение к сериализации Java для JSON (и JSON для Java) вы можете использовать его для форматирования (довольно печатать) JSON:
String niceFormattedJson = JsonWriter.formatJson(jsonString)