如何解决Gson反序列化问题-如果Type参数是子类,则无法反序列化
在变量Generic<Parent> generic
的 Master 类中,我正在main()
中传递子对象。在序列化期间,我得到正确的输出。但是在反序列化Child Object时缺少。任何人都可以提出建议。
public class GenericSample {
public static void main(String[] args) {
Generic<Parent> generic = new Generic<Parent>();
Child child = new Child();
child.setName("I am child");
generic.setT(child);
Gson gson = new Gson();
Master master = new Master();
master.setId(2);
master.setGeneric(generic);
String valMaster = gson.toJson(master);
System.out.println(valMaster);
/*
* Output: {"id":2,"generic":{"t":{"name":"I am child"}}}
*/
Master master2 = gson.fromJson(valMaster,Master.class);
String valMaster2 = gson.toJson(master2);
System.out.println(valMaster2);
/*
* Child Object is missing
* Output: {"id":2,"generic":{"t":{}}}
*/
}
static class Master {
private int id;
private Generic<Parent> generic;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Generic<Parent> getGeneric() {
return generic;
}
public void setGeneric(Generic<Parent> generic) {
this.generic = generic;
}
}
static class Generic<T> {
T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
static class Parent {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
static class Child extends Parent {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
解决方法
问题
Gson尝试将通用值反序列化为Parent
,而不是Child
。由于type
为null
,因此在反序列化的对象中看不到显示为{}
的数据。如果添加child.setType("type");
,则输出将变为:
-
valMaster1
:{"id":2,"generic":{"t":{"name":"I am child","type":"type"}}}
-
valMaster2
:{"id":2,"generic":{"t":{"type":"type"}}}
但是,name
类中不存在字段Parent
,但Child
类中却没有{em> Gem,而Gson根本不知道{{1 }}是(如果是)并且完全忽略该值,这是正确的行为。
解决方案
我发现基本上有两个选择(为简洁起见,我使用all-args构造函数):
-
将上限通用类型参数提升为
Parent
类,并在反序列化时使用Master
和Child
指定特定的com.google.gson.reflect.TypeToken
类型:java.lang.reflect.Type
static class Master<T extends Parent> { private int id; private Generic<T> generic; /* getters,setters and all-args constructor */ }
-
在
Child child = new Child("I am child"); Generic<Parent> generic = new Generic<>(child); Master<Parent> master = new Master<>(2,generic); Gson gson = new Gson(); String valMaster = gson.toJson(master); System.out.println(valMaster); // {"id":2,"generic":{"t":{"name":"I am child"}}} Type type = new TypeToken<Master<Child>>() {}.getType(); Master<Child> master2 = gson.fromJson(valMaster,type); String valMaster2 = gson.toJson(master2); System.out.println(valMaster2); // {"id":2,"generic":{"t":{"name":"I am child"}}}
类内对特定的通用类型Generic<Child>
进行硬编码。反序列化使方法变得更容易,但是设计的灵活性较差:Master
static class Master { private int id; private Generic<Child> generic; /* getters,setters and all-args constructor */ }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。