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,或者在某些情况下它无法工作?
3条答案
按热度按时间nx7onnlm1#
从Gson 2.3.1开始。
不管Gson文档是怎么说的,如果你的类没有一个无参数的构造函数,并且你没有注册任何
InstanceCreater
对象,那么它将创建一个ObjectConstructor
(它构造你的Object),它带有一个UnsafeAllocator
,它使用反射来获取sun.misc.Unsafe
类的allocateInstance
方法来创建你的类的示例。这个
Unsafe
类克服了无参数构造函数的不足,并具有many other dangerous uses .allocateInstance
状态配置执行严修,但不要执行任何建构函式。如果尚未初始化类别,请初始化类别。
所以它实际上并不需要构造函数,而是绕过你的两个参数构造函数,见一些例子here。
如果您有一个无参数的构造函数,Gson将使用一个
ObjectConstructor
,它使用默认的Constructor
,通过调用**我的两点意见:**按照Gson的说法,用一个无参数的构造函数创建类,或者注册一个
InstanceCreator
。使用Unsafe
可能会发现自己处于一个不好的位置。jpfvwuh42#
Jackson库中有一个很好的解决方案,如下所述:
https://stackoverflow.com/a/11838468/2854723
关键是通过Mix-Ins feature告诉序列化程序在使用带参数的构造函数时使用哪些JSON字段。
如果该实体是外部库的一部分,则可以使用Creator feature进行“远程注解”。
iklwldmw3#
以raindev为例,这是可以的,因为JSON中有所有的值,所以它们会覆盖每个变量,即使它们没有初始化。但在许多情况下,可能会有一些 transient 字段,或可选字段,在JSON中没有值。然后,如果你没有一个无参数的构造函数,当有人试图读取它时,该字段将保持为空和NPE。