我正在尝试创建一个JSONMessage类,它可以解析json字符串并将消息中包含的对象添加到List<T> t
。
消息中包含的对象实现了JSONSerialisation接口,并实现了两个方法toJSON()和fromJSON()。
下面的代码不起作用,因为我无法实例化Type T,并且我在行t2.fromJSON...
上收到错误(因为t2尚未初始化)。
我不确定我的方法是否正确以及我尝试的是否可以实现(创建一个通用的JSONMessage),我可以使用它来编码/解析不同类型的对象。如果不可能采用这种方法,我会很感激如何获得类似的结果。
此致
public interface JSONSerialisation {
public JSONObject toJSON();
public void fromJSON(JSONObject jsonObject);
}
public class JSONMessage<T extends JSONSerialisation> {
private List<T> t;
public JSONMessage(String json) {
parseJSONMessage(json);
}
public void parseJSONMessage(String json) {
try {
this.t = new ArrayList<T>();
JSONObject jsonObject;
JSONArray lineItems;
jsonObject = new JSONObject(json);
this.messageHeader = new MessageHeader(jsonObject.getJSONObject("Header"));
lineItems = jsonObject.getJSONArray("Data");
int size = lineItems.length();
for (int i = 0; i < size; i++) {
T t2;
t2.fromJSON(lineItems.getJSONObject(i));
t.add(t2);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
试试这个:
this.t = new ArrayList<JSONSerialisation>();
如果删除该方法中对this
的所有引用,则可以将其设置为静态。只需在范围内创建List
并将其返回。
我不知道仿制药在这里买了什么。您将有多少可能拥有该JSON接口的不同实现?
答案 1 :(得分:0)
看起来您正在尝试替换大多数JSON反序列化库中提供的功能。你会发现它们中的大多数都需要一个参数化的类,作为你所面临的问题的解决方案。这不是最优雅的解决方案,但它会起作用。我会从反序列化类和有状态变量中删除泛型参数:
public class JSONMessage {
public static <T extends JSONSerialisation> Collection<T> parseJSONMessage(Class<T> clazz, String json) {
try {
final JSONObject jsonObject = new JSONObject(json);
final JSONArray lineItems = jsonObject.getJSONArray("Data");
Collection<T> results = new ArrayList<T>(lineItems.size());
for (final JSONElement elem: lineItems) {
T result = clazz.newInstance();
result.fromJSON(elem);
results.add(result);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public JSONMessage() {
super();
}
}
代码显然缺少一些错误处理,我在增强的for循环中编写了一个伪造的JSONElement
类型,但是你得到了一般的想法。祝你好运。
答案 2 :(得分:0)
您是否考虑在JSON消息中包含对象类?
如何实现fromJSON(JSONObject)
的工厂类,以便在不首先拥有对象实例的情况下创建对象的实例?工厂可以使用有关生成JSON的上下文的信息来确定适当的Java类。例如,如果您刚刚调用了Web服务X,则可能知道响应将是Y类型的数据或Z类型的错误消息。
在上面的代码中,如果T有一个子类怎么办?你如何区分它们?
忽略JSON,我想我也会回答关于泛型问题的部分:如果你知道你有一个List,那么T是什么? Java泛型通过类型擦除工作,这意味着在编译期间,许多泛型类型信息被擦除。但是,如果您将POJO序列化为JSON,那就有好消息。对于类,字段和方法保留泛型类型信息,因此如果您有类似这样的类:
class Example extends ArrayList<String> {
private Set<Integer> someIDs;
public Map<String,Long> getLongMap() {
...
}
}
然后可以使用反射来发现该类实现List,其中T是String,someIDs
字段是Set的实例,其中T是Integer,getLongMap
方法返回一个实例其中K是String而V是Long的Map。但是,通过反射API工作以获取此信息可能会非常复杂。我只能识别Collection,Iterator和Enumeration类型的代码可以运行超过100行。如果您有其他选择,我不建议您尝试这样做。