【发布时间】:2014-01-25 00:49:17
【问题描述】:
我的 json 包含任何类型的消息,并且 json 包含一个字符串,说明消息具有哪种类型。
我想反序列化它们并获得 1. 表示消息的消息类型的实例和 2. 主题的实例,其中 T 是消息类型。
举例:
输入1
{
"messageType":"String",
"message": "a string"
}
我希望反序列化后的结果与手动完成的结果相同:
Topic<String> t = new Topic<String>(String.class);
String message = "a string";
输入2
{
"messageType":"Integer",
"message": 1
}
我希望反序列化后的结果与手动完成的结果相同:
Topic<Integer> t = new Topic<Integer>(Integer.class);
Integer message = 1;
输入3
{
"messageType":"MyClass",
"message": {"a": "something", "b": 1}
}
我希望反序列化后的结果与手动完成的结果相同:
Topic<MyClass> t = new Topic<MyClass>(MyClass.class);
MyClass message = new MyClass("something", 1);
输入4
... same with other types ...
我想你明白了。但是现在我需要以通用/抽象的方式以某种方式做到这一点。我试过了,但这不起作用:
private enum MessageType {
STRING(String.class), INTEGER(Integer.class), BOOLEAN(Boolean.class), MYCLASS(MyClass.class);
private Class<?> clazz;
MessageType(Class<?> clazz) {
this.clazz = clazz;
}
}
private static class MyJson {
String topicId;
String messageType;
Object message;
}
MyJson<?> myJson = gson.fromJson(input, MyJson.class);
MessageType type = MessageType.valueOf(myJson.messageType);
Class<?> clazz = type.getClass();
??? message = clazz.newInstance(message);
Topic<???> t = new ?????
我不知道该怎么办?!我需要输入主题和消息,但是如何?以下似乎很糟糕:
@SuppressWarnings("unchecked")
private <T> Topic<T> createTopic(Class<T> typeClass) {
try {
return Topic.class.getConstructor(typeClass).newInstance(typeClass);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Fail");
}
}
【问题讨论】:
-
这正是你所做的。泛型是 Java 中的编译时特性,当您试图从运行时到达的字符串中找出类型时,它们绝对不会为您做任何事情。看起来好像可以的图书馆只是在做你已经到达的引擎盖下的同样不安全的事情。
-
是的,但我现在该怎么做?我的方法不起作用
-
我需要消息类型,但如何获取?
-
如果所有的 possible 值在编译时都是已知的,您可以创建 TypeToken 并让 GSON 使用类型令牌反序列化“消息”的内容,然后将其设置在您的主题。
-
Affe,但是我仍然需要将 messageType 与 typetoken 匹配。或者有没有可能是gson自己猜到了呢?
标签: java json generics serialization gson