Gson user guide states that we should define default no-args constructor for any class to work with Gson properly. Even more, in the javadoc on Gson's InstanceCreator
class said that exception will be thrown if we try to deserialize instance of class missing default constructor and we should use 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.
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?
As of 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 anObjectConstructor
(which constructs your Object) with anUnsafeAllocator
which uses Reflection to get theallocateInstance
method of the classsun.misc.Unsafe
to create your class' instance.This
Unsafe
class goes around the lack of no-args constructor and has many other dangerous uses.allocateInstance
statesSo 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 defaultConstructor
by callingMy 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 usingUnsafe
.There is a good solution in the Jackson library as described here:
https://stackoverflow.com/a/11838468/2854723
The point is to tell the serializer via the Mix-Ins feature which JSON fields to use when using the constructor with arguments.
If that entity is part of an external library then you can "remote annotate" with the Creator feature.