是否必须在Gson处理的类上保留默认构造函数?

时间:2012-11-23 15:43:16

标签: java json gson

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

4 个答案:

答案 0 :(得分: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”)注释参数。其他属性将使用setter和fields设置(其中Gson仅使用字段)。如果需要,您甚至可以提供静态工厂方法而不是ctrs。例如:

public class MyClass {
   private String myString;

   @JsonCreator public static MyClass create(String myString) {
     return new MyClass(myString);
   }
}

答案 1 :(得分:2)

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

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

PS:实际上,我认为JsonDeserializer已经足够了。洞察任何人?

选项2:(请参阅Eugen的回答)考虑使用Genson代替

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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