1

如果我创建一个自定义构造函数,我需要创建一个不带参数的 Gson 吗?

4

4 回答 4

3

事实上,如果你有这样的要求,你可以试试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);
   }
}
于 2012-11-23T16:28:23.200 回答
2

选项 1:是的,除非您创建自己的JsonDeserializerand JsonSerializer,在这种情况下,您的序列化程序可以使用您想要的任何构造函数。

具体来说,如果您的类中有其他要求,例如它们是不可变的,或者如果您想保证初始化后的最小状态,我建议您做一些额外的工作。

PS:实际上,我想JsonDeserializer就足够了。洞察任何人?

选项 2:(参见 Eugen 的回答)考虑改用Genson

选项 3:(请参阅 Robertiano 的回答)保留默认的反序列化器并改为实现InstanceCreator

于 2012-11-23T15:48:58.690 回答
1

如果您想保存 GSON 反序列化器并且您想要的只是创建没有空构造函数的对象实例,那么InstanceCreator这是最好的解决方案。

于 2012-11-23T16:05:26.580 回答
0

是的,但是没有参数的构造函数可以是私有的。因此,您可以拥有一个带有 args 的公共构造函数(不可变类)和一个没有参数的私有构造函数,仅用于反序列化目的。

这不是一个非常优雅的解决方案,但至少您不需要编写额外的组件。

于 2016-11-03T13:42:09.990 回答