Search code examples
javaandroidgsonto-json

Gson toJson(), weird behavior (produce empty json)


I have problems serializing / deserializing this class with Gson:

public class Test {

    @SerializedName("id")
    private String mId;

    public String getId() { return mId; }

    public static Test fromJson(String json) { return new Gson().fromJson(json, Test.class); }
    public String toJson() { return new Gson().toJson(this, Test.class); }
}

If I run this:

Test test = Test.fromJson("{\"id\":\"1465988493\"}");
Log.i(TAG, "Test: " + test.toJson());
//Log.i(TAG, "Test id: " + test.getId());

It prints:

Test: {}

But if I run this:

Test test = Test.fromJson("{\"id\":\"1465988493\"}");
Log.i(TAG, "Test: " + test.toJson());
Log.i(TAG, "Test id: " + test.getId());

It works as expected and prints:

Test: {"id":"1465988493"}

Test id: 1465988493

So calling the getter AFTER calling toJson made toJson() to work. WTF???

Last thing, if I initialize the id to null:

public class Test {

    @SerializedName("id")
    private String mId = null; // <- Init to null

    public String getId() { return mId; }

    public static Test fromJson(String json) { return new Gson().fromJson(json, Test.class); }
    public String toJson() { return new Gson().toJson(this, Test.class); }
}

Then everything works as expected, and this code:

String testJson = "{\"id\":\"1465988493\"}";
Test test = Test.fromJson(testJson);
Log.i(TAG, "Test: " + test.toJson());
//Log.i(TAG, "Test id: " + test.getId());

Prints:

Test: {"id":"1465988493"}

So, I have the solution (initialize all my fields to null), but I'd like to understand what's wrong??


Solution

  • There is just proguard problem. If you use proguard just keep in mind the proguard can remove some fields from class if you don't use it. For example your app doesn't use getters of class. So easy way just add annotation to keep it like:

    @SerializedName("id")
    @Keep
    private String mId;
    

    Or add keep rule to your proguard file.