默认的无参数构造函数对于Gson是必需的吗?

8tntrjer  于 2022-11-06  发布在  其他
关注(0)|答案(3)|浏览(219)

Gson user guide声明,我们应该为任何类定义默认的无参数构造函数,以便正确使用Gson。更重要的是,在Gson的InstanceCreator类上的javadoc中,如果我们试图对缺少默认构造函数的类的示例进行反序列化,则会抛出异常,并且在这种情况下,我们 * 应该 * 使用InstanceCreator。然而,我试着用缺少默认构造函数的类测试Gson,序列化和反序列化都能正常工作。
下面是反序列化的一段代码。一个没有非参数构造函数的类:

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

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

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

测试仪:

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

这很好。
所以我的问题是:我是否可以在不需要默认构造函数情况下使用Gson,或者在某些情况下它无法工作?

nx7onnlm

nx7onnlm1#

从Gson 2.3.1开始。
不管Gson文档是怎么说的,如果你的类没有一个无参数的构造函数,并且你没有注册任何InstanceCreater对象,那么它将创建一个ObjectConstructor(它构造你的Object),它带有一个UnsafeAllocator,它使用反射来获取sun.misc.Unsafe类的allocateInstance方法来创建你的类的示例。
这个Unsafe类克服了无参数构造函数的不足,并具有many other dangerous uses . allocateInstance状态
配置执行严修,但不要执行任何建构函式。如果尚未初始化类别,请初始化类别。
所以它实际上并不需要构造函数,而是绕过你的两个参数构造函数,见一些例子here
如果您有一个无参数的构造函数,Gson将使用一个ObjectConstructor,它使用默认的Constructor,通过调用

yourClassType.getDeclaredConstructor(); // ie. empty, no-args

**我的两点意见:**按照Gson的说法,用一个无参数的构造函数创建类,或者注册一个InstanceCreator。使用Unsafe可能会发现自己处于一个不好的位置。

jpfvwuh4

jpfvwuh42#

Jackson库中有一个很好的解决方案,如下所述:
https://stackoverflow.com/a/11838468/2854723
关键是通过Mix-Ins feature告诉序列化程序在使用带参数的构造函数时使用哪些JSON字段。
如果该实体是外部库的一部分,则可以使用Creator feature进行“远程注解”。

iklwldmw

iklwldmw3#

以raindev为例,这是可以的,因为JSON中有所有的值,所以它们会覆盖每个变量,即使它们没有初始化。但在许多情况下,可能会有一些 transient 字段,或可选字段,在JSON中没有值。然后,如果你没有一个无参数的构造函数,当有人试图读取它时,该字段将保持为空和NPE。

相关问题