Java Gson反序列化问题-如果类型参数为子类,则无法反序列化
在变量Java Gson反序列化问题-如果类型参数为子类,则无法反序列化,java,generics,gson,json-deserialization,Java,Generics,Gson,Json Deserialization,在变量Generic的Master类中,我正在main()中传递一个子对象。在序列化过程中,我得到了正确的输出。但在反序列化子对象时丢失。谁能给我一些建议 public class GenericSample { public static void main(String[] args) { Generic<Parent> generic = new Generic<Parent>(); Child child = new Chi
Generic
的Master类中,我正在main()
中传递一个子对象。在序列化过程中,我得到了正确的输出。但在反序列化子对象时丢失。谁能给我一些建议
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;
}
}
}
public类GenericSample{
公共静态void main(字符串[]args){
泛型=新泛型();
子项=新子项();
child.setName(“我是孩子”);
generic.setT(儿童);
Gson Gson=新的Gson();
母版=新母版();
硕士学位证书(2);
硕士学位(通用);
字符串valMaster=gson.toJson(master);
系统输出打印LN(valMaster);
/*
*输出:{“id”:2,“generic”:{“t”:{“name”:“我是孩子”}}
*/
Master master2=gson.fromJson(valMaster,Master.class);
字符串valMaster2=gson.toJson(master2);
系统输出打印LN(valMaster2);
/*
*缺少子对象
*输出:{“id”:2,“generic”:{“t”:{}
*/
}
静态类主控{
私有int-id;
私有通用;
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}
公共泛型getGeneric(){
返回泛型;
}
公共void setGeneric(Generic-Generic){
this.generic=generic;
}
}
静态类泛型{
T;
公共T getT(){
返回t;
}
公共无效集合(T){
t=t;
}
}
静态类父类{
私有字符串类型;
公共字符串getType(){
返回类型;
}
公共void集合类型(字符串类型){
this.type=type;
}
}
静态类子级扩展父级{
私有字符串名称;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
}
问题
Gson尝试将泛型值反序列化为父级
,而不是子级
。由于存在type
为null
,因此在显示为{}
的反序列化对象中看不到任何数据。如果添加child.setType(“type”)代码>然后输出变为:
valMaster1
:{“id”:2,“generic”:{“t”:{“name”:“我是孩子”,“type”:“type”}}
valMaster2
:{“id”:2,“generic”:{“t”:{“type”:“type”}}
但是,父类
中不存在字段名称
,而子类
类和Gson根本不知道它是父类
的哪个子类(如果是),并且完全忽略该值,这是一种正确的行为
解决方案
我发现基本上有两种选择(为了简洁起见,我使用了所有参数构造函数):
将上限泛型类型参数提升到主类
类,并使用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=新孩子(“我是孩子”);
通用=新通用(子);
母版=新母版(2,通用);
Gson Gson=新的Gson();
字符串valMaster=gson.toJson(master);
系统输出打印LN(valMaster);
//{“id”:2,“泛型”:{“t”:{“name”:“我是孩子”}}
Master master2=gson.fromJson(valMaster,Master.class);
字符串valMaster2=gson.toJson(master2);
系统输出打印LN(valMaster2);
//{“id”:2,“泛型”:{“t”:{“name”:“我是孩子”}}
我确信OP要求的是完美的往返序列化/反序列化,而不是临时硬编码子类。@fluffy:你读过第一对代码片段了吗?它没有说硬编码。是的,我说了。有Type Type=new-TypeToken(){}.getType()代码>在你的解决方案1中。请在我看来不错的位置找到一个往返解决方案。但是,您必须删除从父项声明的字段type
。谢谢我学到了一些新东西。请随意添加答案。
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"}}}
static class Master {
private int id;
private Generic<Child> generic;
/* getters, setters and all-args constructor */
}
Child child = new Child("I am child");
Generic<Child> generic = new Generic<>(child);
Master 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"}}}
Master master2 = gson.fromJson(valMaster, Master.class);
String valMaster2 = gson.toJson(master2);
System.out.println(valMaster2);
// {"id":2,"generic":{"t":{"name":"I am child"}}}