Gson user guide指出,我们应该为任何类定义默认的no-args构造函数,以使其与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而不需要使用默认构造函数,或者在任何情况下它都将不起作用?
最佳答案
从Gson 2.3.1开始。
无论Gson文档说什么,如果您的类没有no-args构造函数,并且您尚未注册任何InstanceCreater
对象,则它将创建一个ObjectConstructor
(用于构造您的Object),该UnsafeAllocator
使用Reflection来获取类allocateInstance
的sun.misc.Unsafe
方法来创建您的类的实例。
这个 Unsafe
class缺少no-args构造函数,并且具有many other dangerous uses。 allocateInstance
状态
因此,它实际上不需要构造函数,并且会绕过您的两个参数构造函数。查看一些示例here。
如果您确实有一个无参数的构造函数,那么Gson将使用ObjectConstructor
,该Constructor
通过调用该默认的InstanceCreator
yourClassType.getDeclaredConstructor(); // ie. empty, no-args
我的2分:遵循Gson所说的,并使用no-arg构造函数创建类或注册
Unsafe
。使用ojit_code可能会发现自己处于不利位置。