You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the enum type is used as the key of one map, if there is @SerializedName("name") at the declaration of the enum items, the Gson serialization and deserialization do NOT work well.
Following is the bad case
importcom.google.gson.annotations.SerializedName;
publicenumRoomIdentifier {
@SerializedName("MARKER_NAME") // Here is the bad caseROOM_NAME;
}
Test code is here
publicvoidtestConvert() {
RoomIdentifierid = RoomIdentifier.ROOM_NAME;
Map<RoomIdentifier, String> slots = newHashMap<SlotIdentifier, String>();
slots.put(RoomIdentifier.ROOM_NAME,"ROOM_NAME_TEST");
StringstrSerialized = gson.toJson(slots);
Typetype = newTypeToken<Map<RoomIdentifier, String>>() {
}.getType();
Map<RoomIdentifier, String> slotsDeserialized = gson.fromJson(strSerialized, type);
System.out.println(gson.toJson(id)); // "MARKER_NAME" //As expect, SerializedName is usedSystem.out.println(strSerialized); // {"ROOM_NAME":"ROOM_NAME_TEST"} // the key name is not SerializedNameSystem.out.println(slotsDeserialized); // {null=ROOM_NAME_TEST} //The key is null
}
Root cause
In the serialization function GSON::toJson , the MapTypeAdapterFactory::Adapter uses String.valueOf(entry.getKey()) to generate the key. @SerializedName("name") ("MARKER_NAME" in the example) is NOT used at all. Here is Gson code
But in the deserialization function GSON::fromJson , EnumTypeAdapter is used to deserialize the key(here is code). If one field is marked by @SerializedName("name") , the original name string ("ROOM_NAME" in the example ) could NOT be recognized, null is returned.
The text was updated successfully, but these errors were encountered:
It is unfortunate that Gson uses String.valueOf for map keys, since this behavior is not obvious to the user and most likely not symmetric with deserialization, as shown here.
Personally I think it would make sense to special-case enums for map key serialization since it is guaranteed that they have a String value. To remain as backward compatible as possible, by default String.valueOf could be used for enums as well (which is equivalent to Enum.name(), unless overridden), but if the enum constant is annotated with @SerializedName, then its value should be used. This should in most cases not cause any issues, even when Enum.toString() is overridden and used intentionally by the user for serialization.
Note however, that I am not a member of this project.
When the enum type is used as the key of one map, if there is
@SerializedName("name")
at the declaration of the enum items, the Gson serialization and deserialization do NOT work well.Following is the bad case
Test code is here
Root cause
GSON::toJson
, the MapTypeAdapterFactory::Adapter usesString.valueOf(entry.getKey())
to generate the key.@SerializedName("name")
("MARKER_NAME" in the example) is NOT used at all. Here is Gson codeGSON::fromJson
, EnumTypeAdapter is used to deserialize the key(here is code). If one field is marked by@SerializedName("name")
, the original name string ("ROOM_NAME" in the example ) could NOT be recognized,null
is returned.The text was updated successfully, but these errors were encountered: