如果我创建一个自定义构造函数,我需要创建一个不带参数的 Gson 吗?
4 回答
事实上,如果你有这样的要求,你可以试试Genson库。它可以使用带参数的构造函数反序列化对象。要求是参数的名称必须与 json 中的名称匹配。这是一个例子:
public static class MyClass {
public final String someString;
public MyClass(String someString) {
this.someString = someString;
}
}
String json = "{\"someString\": \"foo bar\"}";
// enable this feature
Genson genson = new Genson.Builder().setWithDebugInfoPropertyNameResolver().create();
MyClass mc = genson.deserialize(json, MyClass.class);
编辑:在这种情况下,我认为 Genson 比 Gson 有几个优势。
编写自定义反序列化器会很乏味,您需要为每个不提供无参数构造函数的类编写另一个反序列化器。我觉得太过分了...
编写 InstanceCreator 更容易,但我认为这不是正确的方法。实际上,您仍然需要为每个类编写一个 InstanceCreator,最大的缺点是您没有反序列化的值。因此,除了将 null 和常量作为参数传递之外,您无能为力...
我认为处理带参数的构造函数是 Gensons 的优势之一。它不需要任何额外的代码,它有效地将 json 流中的值作为参数传递,如果你想使用另一个属性名称,你可以用 @JsonProperty("newName") 注释参数。其他属性将使用设置器和字段设置(其中 Gson 仅使用字段)。如果需要,您甚至可以提供静态工厂方法而不是 ctrs。例如 :
public class MyClass {
private String myString;
@JsonCreator public static MyClass create(String myString) {
return new MyClass(myString);
}
}
选项 1:是的,除非您创建自己的JsonDeserializer
and JsonSerializer
,在这种情况下,您的序列化程序可以使用您想要的任何构造函数。
具体来说,如果您的类中有其他要求,例如它们是不可变的,或者如果您想保证初始化后的最小状态,我建议您做一些额外的工作。
PS:实际上,我想JsonDeserializer
就足够了。洞察任何人?
选项 2:(参见 Eugen 的回答)考虑改用Genson
选项 3:(请参阅 Robertiano 的回答)保留默认的反序列化器并改为实现InstanceCreator
如果您想保存 GSON 反序列化器并且您想要的只是创建没有空构造函数的对象实例,那么InstanceCreator
这是最好的解决方案。
是的,但是没有参数的构造函数可以是私有的。因此,您可以拥有一个带有 args 的公共构造函数(不可变类)和一个没有参数的私有构造函数,仅用于反序列化目的。
这不是一个非常优雅的解决方案,但至少您不需要编写额外的组件。