misaka misaka - 16 days ago 7
Java Question

GSON is serializing enum properly, but deserializes it as a String

HashSet<Skill> tmp = new HashSet<Skill>();
tmp.add(Skill.WOODCUTTING);
tmp.add(Skill.FIREMAKING);
String j;
System.out.println(j = new GsonBuilder().create().toJson(tmp));
System.out.println(new GsonBuilder().create().fromJson(j, HashSet.class));
for (Object e : new GsonBuilder().create().fromJson(j, HashSet.class)) {
System.out.println(e.getClass());
System.out.println(e.toString());
}


Skill is an enum defined like so:

@SerializedName("w") WOODCUTTING("Woodcutting"),
@SerializedName("m") MINING("Mining"),
@SerializedName("f") FISHING("Fishing"),


The output of the code above:

[11:04:18 INFO]: ["fir","w"]
[11:04:18 INFO]: [w, fir]
[11:04:18 INFO]: class java.lang.String
[11:04:18 INFO]: false
[11:04:18 INFO]: w
[11:04:18 INFO]: class java.lang.String
[11:04:18 INFO]: false
[11:04:18 INFO]: fir


As you can see, it first builds the Gson properly, but it then appears to deserialize it as a string rather than the enum. I'm a little lost as to what's going on here - aren't enums supported by Gson by default?

I've also tried registering a TypeAdapterFactory that's meant to serialize/deserialize enums. Although the write() method of the TypeAdapters it creates is called, the read() method never is.

Answer

The following is a proper way of doing enum deserialisation with Gson.

List<Skill> items = new Gson().<List<Skill>>fromJson(json, new TypeToken<List<Skill>>(){}.getType())