我在使用GSON对我的对象结构进行序列化和反序列化时遇到了一个问题。为了描述这个问题,我必须描述一下我的类结构。
我有一个java抽象类,我们把它命名为 "A". 还有 "BA"、"CA"、"DA "等类也是抽象的,它们扩展了 "A "类。它们每个类都有自己的构造函数,非但不是arg。最后还有几个(很多!)类,它们扩展了 "BC",或 "CA "或 "DA"。这些 "底层 "类的实例被保存在 "ArrayList "列表中。
现在,我试图将这个数组列表 "json化"。为了创建Json字符串,我使用了这段代码。
Gson gs = new Gson();
Type listOfTestObject = new TypeToken<List<A>>(){}.getType();
String rez = gs.toJson(getListOfAs(), listOfTestObject);
我试图用这个(在另一个类中)来反序列化Json:
Type listOfTestObject = new TypeToken<ArrayList<A>>(){}.getType();
ArrayList<A> listOfAs = gs.fromJson(jsonREZString, listOfTestObject);
但上面的代码却抛出了这个:
Unable to invoke no-args constructor for class packagename.A. Register an InstanceCreator with Gson for this type may fix this problem.
现在,我在 "A "类中创建了一个非args的构造函数,但是没有成功。我读过 "InstanceCreator",但看起来我必须为每个扩展 "A "的具体类创建一个 "InstanceCreator"。是吗?我不能这样做,因为我有很多(很多!)类通过 "BA"、"CA "或 "DA "来扩展 "A"。
我错过了什么?我怎样才能简单地反序列化(序列化似乎不错)这个复杂的结构,而不为每个类型添加自定义的反序列化代码?
事实上,你在这里可能有2个不同的问题。
1) 你有多态类型,因此你可能想把对象序列化为他们的具体类型,而不是A.2) 你想反序列化为不提供无arg ctrs的具体类型。
Gson不支持1 & 2,有一个1的扩展,但我从来没有用过它。
也许可以 Genson 解决了你的问题,它同时支持1 & 2。
Genson genson = new Genson.Builder()
// enables polymorphic types support
.setWithClassMetadata(true)
// enables no arg support
.setWithDebugInfoPropertyNameResolver(true)
.create();
// will look like: [{"@class": "com.xxx.SomeConcreteClass", ...}, {"@class": "com.XXX.OtherClass"}]
String json = genson.serialize(getListOfAs());
List<A> listOfA = genson.deserialize(json, new GenericType<List<A>>() {});
你不需要在序列化过程中指定类型,除非你想让输出中只出现父字段。
例:genson.serialize(getListOfAs(),GenericType>(){})将只序列化A的属性,你也可以通过在构建器上设置UseRuntimeTypeForSerialization(true)来强制genson始终使用运行时类型。
另外,如果你不想让 impl 的细节泄露在 json 表示中,你可以为你的类型定义别名(builder.addAlias("someAlias", SomeClass.class),它们将被用来代替完整的包+类名。