Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Gson.toJson会将泛型字段序列化为空JSON对象?_Java_Gson - Fatal编程技术网

Java 为什么Gson.toJson会将泛型字段序列化为空JSON对象?

Java 为什么Gson.toJson会将泛型字段序列化为空JSON对象?,java,gson,Java,Gson,我有一个泛型类,其中包含一个T类型的字段,Gson将该字段序列化为空对象。我已经在下面包含了代码来演示这个问题。读回JSON似乎很好(只要提供正确的类型标记) import java.lang.reflect.Type; 导入com.google.gson.gson; 导入com.google.gson.reflect.TypeToken; 公共类GsonIssue{ 静态类抽象事物{ 私有字符串fieldA=“valueA”; 公共字符串getFieldA(){ 返回场A; } 公共无效集合字

我有一个泛型类,其中包含一个T类型的字段,Gson将该字段序列化为空对象。我已经在下面包含了代码来演示这个问题。读回JSON似乎很好(只要提供正确的类型标记)

import java.lang.reflect.Type;
导入com.google.gson.gson;
导入com.google.gson.reflect.TypeToken;
公共类GsonIssue{
静态类抽象事物{
私有字符串fieldA=“valueA”;
公共字符串getFieldA(){
返回场A;
}
公共无效集合字段A(字符串字段A){
this.fieldA=fieldA;
}
@凌驾
公共字符串toString(){
返回“AbstractThing[fieldA=“+fieldA+”]”;
}
}
静态类事物扩展了抽象事物{
私有字符串fieldB=“valueB”;
@凌驾
公共字符串toString(){
返回“Thing[fieldB=“+fieldB+”,fieldA=“+getFieldA()+””;
}
}
静态类包装器{
私人物品;
私有字符串standardField=“标准值”;
公共包装器(T abstractThing){
this.abstractThing=抽象事物;
}
@凌驾
公共字符串toString(){
返回“包装器[abstractThing=“+abstractThing+”,standardField=“+standardField+”]”;
}
}
公共静态void main(字符串[]args){
包装器=新包装器(newthing());
Gson Gson=新的Gson();
字符串json=gson.toJson(包装器);
System.out.println(json);
//打印:{“abstractThing”:{},“standardField”:“standard value”}
//所以standardField是正确序列化的,但不是抽象的东西。
//但是,如果我们手动构造预期的json字符串,并将其解析回来,我们就会得到预期的对象结构
json=“{\“standardField\”:\“一些文本\”,“+
“\'abstractThing\':{\'fieldB\':\'arb value\',\'fieldA\':\'Other arb value\'}”;
Type Type=new-TypeToken(){}.getType();
objectfromJSON=gson.fromJson(json,类型);
System.out.println(fromJson);
//打印:包装器[abstractThing=Thing[fieldB=arb值,fieldA=另一个arb值],standardField=一些文本]
//这是意料之中的
}
}
来自他们的文档:

当您调用toJson(obj)时,Gson调用obj.getClass()以获取有关要序列化的字段的信息。类似地,通常可以在fromJson(json,MyClass.class)方法中传递MyClass.class对象。如果对象是非泛型类型,则此操作非常有效。但是,如果对象是泛型类型,那么由于Java类型擦除,泛型类型信息将丢失

可以通过为泛型类型指定正确的参数化类型来解决此问题。您可以使用TypeToken类来实现这一点

它们为
列表提供了以下示例:

Type listType=new-TypeToken(){}.getType();
toJson(myStrings,listType);
所以对于你的代码,你需要

Type myType = new TypeToken<Wrapper<Thing>>() {}.getType();
String json = gson.toJson(wrapper, myType);
typemytype=newtypetoken(){}.getType();
字符串json=gson.toJson(包装器,myType);

谢谢-这确实有效,但似乎与本节相矛盾:在本节中,
集合
是在没有类型标记的情况下序列化的。你能解释一下我的示例和手册示例之间的区别吗?我怀疑他们有专门处理集合和数组的代码,但除此之外。。。不知道,看起来是这样的。Java泛型通常比处理原始对象浪费更多的时间。谢谢你的帮助。
Type myType = new TypeToken<Wrapper<Thing>>() {}.getType();
String json = gson.toJson(wrapper, myType);