Gson用户指南指出,我们应该为任何可以正常使用Gson的类定义默认的无参数构造函数。甚至,在Gson 类的javadoc中InstanceCreator说,如果我们尝试对缺少默认构造函数的类实例进行反序列化,则会抛出异常,在这种情况下 应 使用该异常InstanceCreator。但是,我尝试对缺少默认构造函数的类使用Gson进行测试,并且序列化和反序列化工作都没有任何麻烦。
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. }
和一个测试:
@Test public void deserializeMushroom() { assertEquals( new Mushroom("Fly agaric", 4.0), new Gson().fromJson( "{name:\"Fly agaric\", diameter:4.0}", Mushroom.class)); }
效果很好。
所以我的问题是:我是否 可以实际使用Gson而不需要使用默认构造函数,或者在任何情况下它都不起作用?
从Gson 2.3.1开始。
不管GSON文档是这么说,如果你的类没有一个无参数的构造函数,你还没有注册的任何InstanceCreater对象,那么它会创建一个ObjectConstructor与(它构造你的对象)UnsafeAllocator,它使用反射来获取allocateInstance的方法类sun.misc.Unsafe来创建您的类的实例。
InstanceCreater
ObjectConstructor
UnsafeAllocator
allocateInstance
sun.misc.Unsafe
这个Unsafe类是绕着缺乏无参数的构造函数,有许多其他用途的危险。allocateInstance状态
Unsafe
分配实例,但不运行任何构造函数。如果尚未初始化该类,则将其初始化。
因此,它实际上不需要构造函数,并且会绕过您的两个参数构造函数。在这里看到一些例子。
如果您确实有一个无参数的构造函数,那么Gson将使用ObjectConstructor,Constructor通过调用以下命令使用该默认值
Constructor
yourClassType.getDeclaredConstructor(); // ie. empty, no-args
我的2美分: 按照Gson的说法,并使用无参数构造函数创建类或注册一个InstanceCreator。使用,您可能会发现自己处于不利位置Unsafe。