Reputation: 17181
If I create a custom constructor, need I create one with no arguments to use with Gson?
Upvotes: 1
Views: 2678
Reputation: 4427
Yes, but the constructor with no-args can be private. Therefore you can have a public constructor with args (the immutable class) and one private constructor with no-args just for deserialization purpose.
It's not a very elegant solution but at least you don't need to write extra components.
Upvotes: 0
Reputation: 15675
Option 1: Yes, unless you create your own JsonDeserializer
and JsonSerializer
, in which case, your serializers can use whatever constructor you want.
Specifically, I would advise you to do the extra bit of work if you have other requirements in your classes, such as them being immutable, or if you want to guarantee a minimum state after initialization.
PS: actually, I supose the JsonDeserializer
is enough. Insights anyone?
Option 2: (see Eugen's answer) consider using Genson instead
Option 3: (see Robertiano's answer) keep the default deserializers and implement InstanceCreator instead
Upvotes: 2
Reputation: 5916
In fact if you have such requirements you can try Genson library. It can deserialize objects using a constructor with arguments. The requirement is that the name of the parameters must match those in the json. Here is an example:
public static class MyClass {
public final String someString;
public MyClass(String someString) {
this.someString = someString;
}
}
String json = "{\"someString\": \"foo bar\"}";
// enable this feature
Genson genson = new Genson.Builder().setWithDebugInfoPropertyNameResolver().create();
MyClass mc = genson.deserialize(json, MyClass.class);
EDIT: I think Genson has a couple of advantages over Gson in that case.
Writing a custom deserializer would be tedious and you will need to write another deserializer for each class that does not provide a no arg constructor. I think it is too much...
Writing an InstanceCreator is easier but I don't think it is the right way to go. Indeed you will still need to write an InstanceCreator per class, and biggest disadvantage is that you don't have the values being deserialized. So except passing null and constants as arguments you can't do much...
I think handling constructors with arguments is one of Gensons strengths. It does not require any additional code, it effectively passes as arguments the values from the json stream and you can annotate parameters with @JsonProperty("newName") if you want to use another property name. The other properties will be set using setters and fields (where Gson uses only fields). You can even provide static factory methods instead of ctrs if you want. For example :
public class MyClass {
private String myString;
@JsonCreator public static MyClass create(String myString) {
return new MyClass(myString);
}
}
Upvotes: 3
Reputation: 352
If you want to conserve GSON deserializer and all you want is to create instances of objects without empty constructor, InstanceCreator
is best solution.
Upvotes: 1