Gson是否必须使用默认的no-args构造函数?

时间:2013-09-05 20:11:07

标签: java json gson default-constructor

Gson user guide声明我们应该为任何类定义默认的no-args构造函数以正确使用Gson。更重要的是,在Gson的InstanceCreator类的javadoc中,如果我们尝试反序列化缺少默认构造函数的类的实例,并且我们应该使用{{1}在这种情况下。但是,我尝试使用缺少默认构造函数的类来测试使用Gson,并且序列化和反序列化工作没有任何问题。

以下是deserializaiton的代码。没有非args构造函数的类:

InstanceCreator

和测试:

public class Mushroom {
    private String name;
    private double diameter;

    public Mushroom(String name, double diameter) {
        this.name = name;
        this.diameter = diameter;
    }

    //equals(), hashCode(), etc.
}

工作正常。

所以我的问题是:我是否真的可以使用Gson而无需使用默认构造函数,或者在任何情况下它都不起作用?

3 个答案:

答案 0 :(得分:83)

自Gson 2.3.1。

无论Gson文档说什么,如果你的类没有no-args构造函数并且你没有注册任何InstanceCreater个对象,那么它将创建一个ObjectConstructor(构建你的Object UnsafeAllocator使用Reflection来获取类allocateInstance的{​​{1}}方法来创建类的实例。

这个Unsafe class围绕缺少no-args构造函数而且many other dangerous usessun.misc.Unsafe个州

  

分配实例但不运行任何构造函数。初始化   如果还没有上课的话。

所以它实际上并不需要构造函数,而是会绕过你的两个参数构造函数。请参阅一些示例here

如果你有一个no-args构造函数,Gson将使用allocateInstance通过调用

来使用默认ObjectConstructor
Constructor

我的2美分:按照Gson的说法,使用no-arg构造函数创建类或注册yourClassType.getDeclaredConstructor(); // ie. empty, no-args 。使用InstanceCreator可能会发现自己处于不利位置。

答案 1 :(得分:1)

这里描述的Jackson库中有一个很好的解决方案:

https://stackoverflow.com/a/11838468/2854723

重点是通过Mix-Ins feature告诉序列化程序在使用带参数的构造函数时要使用哪些JSON字段。

如果该实体是外部库的一部分,那么您可以远程注释"使用Creator feature

答案 2 :(得分:-1)

对于raindev的例子,它没问题,因为你的JSON中有所有的值,所以即使他们没有初始化,它们也会覆盖每个变量。但在许多情况下,可能有一些 Transient 字段,或在 JSON 中没有值的可选字段。然后,如果您没有无参数构造函数,则当有人尝试读取该字段时,该字段将保持为 null 和 NPE。