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

rai*_*dev 51 java json default-constructor gson

Gson用户指南声明我们应该为任何类定义默认的no-args构造函数以正确使用Gson.更重要的是,在Gson 类的javadoc中,InstanceCreator如果我们尝试反序列化缺少默认构造函数的类的实例,那么将抛出异常,我们应该InstanceCreator在这种情况下使用.但是,我尝试使用缺少默认构造函数的类来测试使用Gson,并且序列化和反序列化工作都没有任何问题.

这是deserializaiton的一段代码.没有非args构造函数的类:

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

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

    //equals(), hashCode(), etc.
}
Run Code Online (Sandbox Code Playgroud)

和测试:

@Test
public void deserializeMushroom() {
    assertEquals(
            new Mushroom("Fly agaric", 4.0),
            new Gson().fromJson(
                    "{name:\"Fly agaric\", diameter:4.0}", Mushroom.class));
}
Run Code Online (Sandbox Code Playgroud)

哪个工作正常.

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

Sot*_*lis 87

截至Gson 2.3.1.

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

这个Unsafe绕过缺少no-args构造函数,还有许多其他危险的用法.allocateInstance状态

分配实例但不运行任何构造函数.如果尚未进行,则初始化该类.

所以它实际上并不需要构造函数,而是会绕过你的两个参数构造函数.在这里看一些例子.

如果你有一个no-args构造函数,Gson将使用一个通过调用ObjectConstructor使用该默认值Constructor

yourClassType.getDeclaredConstructor(); // ie. empty, no-args
Run Code Online (Sandbox Code Playgroud)

我的2美分:遵循Gson所说的并使用无参数构造函数创建类或注册InstanceCreator.您可能会发现自己处于不利地位Unsafe.

  • 根据[https://sites.google.com/site/gson/gson-user-guide#TOC-Using-Gson](https://sites.google.com/site/gson/gson-user-guide# TOC-Using-Gson)您可以使用私有构造函数来防止使用不安全的.根据我的测试,当我使用私有构造函数时,GSON使用以下方法:com.google.gson.internal.newDefaultConstructor当我删除私有构造函数时,GSON使用以下方法:com.google.gson.internal. newUnsafeAllocator (3认同)