Java Gson 是否必须使用默认的无参数构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18645050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is default no-args constructor mandatory for Gson?
提问by raindev
Gson user guidestates that we should define default no-args constructor for any class to work with Gson properly. Even more, in the javadocon Gson's InstanceCreator
class said that exception will be thrown if we try to deserialize instance of class missing default constructor and we shoulduse InstanceCreator
in such cases. However, I've tried to test use Gson with class lacking default constructor and both serialization and deserialization work without any trouble.
Gson 用户指南指出,我们应该为任何类定义默认的无参数构造函数以正确使用 Gson。更重要的是,在Gson类的javadoc 中InstanceCreator
说,如果我们尝试反序列化缺少默认构造函数的类的实例,则会抛出异常,我们应该InstanceCreator
在这种情况下使用。但是,我尝试使用 Gson 测试缺少默认构造函数的类,并且序列化和反序列化工作都没有任何问题。
Here is the piece of code for deserializaiton. A class without non-args constructor:
这是反序列化的一段代码。没有非参数构造函数的类:
public class Mushroom {
private String name;
private double diameter;
public Mushroom(String name, double diameter) {
this.name = name;
this.diameter = diameter;
}
//equals(), hashCode(), etc.
}
and a test:
和一个测试:
@Test
public void deserializeMushroom() {
assertEquals(
new Mushroom("Fly agaric", 4.0),
new Gson().fromJson(
"{name:\"Fly agaric\", diameter:4.0}", Mushroom.class));
}
which works fine.
这工作正常。
So my question is: could I actually use Gson without need to have default constructor or there is any circumstances when it will not work?
所以我的问题是:我可以在不需要默认构造函数的情况下实际使用 Gson 还是在任何情况下它都不起作用?
采纳答案by Sotirios Delimanolis
As of Gson 2.3.1.
从 Gson 2.3.1 开始。
Regardless of what the Gson documentation says, if your class doesn't have an no-args constructor and you have not registered any InstanceCreater
objects, then it will create an ObjectConstructor
(which constructs your Object) with an UnsafeAllocator
which uses Reflection to get the allocateInstance
method of the class sun.misc.Unsafe
to create your class' instance.
不管 Gson 文档怎么说,如果你的类没有无参数构造函数并且你没有注册任何InstanceCreater
对象,那么它会创建一个ObjectConstructor
(它构造你的对象),UnsafeAllocator
它使用反射来获取allocateInstance
方法类sun.misc.Unsafe
来创建您的类的实例。
This Unsafe
classgoes around the lack of no-args constructor and has many other dangerous uses. allocateInstance
states
这个Unsafe
类解决了没有无参数构造函数的问题,并有许多其他危险的用途。allocateInstance
状态
Allocate an instance but do not run any constructor. Initializes the class if it has not yet been.
分配一个实例但不运行任何构造函数。如果尚未初始化类,则对其进行初始化。
So it doesn't actually need a constructor and will go around your two argument constructor. See some examples here.
所以它实际上并不需要一个构造函数,并且会绕过你的两个参数构造函数。请参阅此处的一些示例。
If you do have a no-args constructor, Gson will use an ObjectConstructor
which uses that default Constructor
by calling
如果您确实有一个无参数构造函数,Gson 将使用一个通过调用ObjectConstructor
使用该默认值Constructor
的
yourClassType.getDeclaredConstructor(); // ie. empty, no-args
My 2 cents:Follow what Gson says and create your classes with a no-arg constructor or register an InstanceCreator
. You might find yourself in a bad position using Unsafe
.
我的 2 美分:遵循 Gson 所说的并使用无参数构造函数创建您的类或注册一个InstanceCreator
. 您可能会发现使用Unsafe
.
回答by thomas.mc.work
There is a good solution in the Hymansonlibrary as described here:
Hymanson库中有一个很好的解决方案,如下所述:
https://stackoverflow.com/a/11838468/2854723
https://stackoverflow.com/a/11838468/2854723
The point is to tell the serializer via the Mix-Ins featurewhich JSON fields to use when using the constructor with arguments.
关键是通过Mix-Ins 功能告诉序列化程序在使用带参数的构造函数时要使用哪些 JSON 字段。
If that entity is part of an external library then you can "remote annotate" with the Creator feature.
如果该实体是外部库的一部分,那么您可以使用Creator 功能“远程注释” 。