我需要为某些对象实现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);
我应该如何修改此方法?
答案 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
}
}