Im Folgenden ist das Klassendiagramm der Problemdomäne. Wir haben JSON decodierte Nachrichten mit unterschiedlicher Semantik, die verschiedene Methoden im Code (initialisieren, aktualisieren) für verschiedene Sichten auslösen.Gson deserialize polymorphes Mitglied Listenvariable ist null
Die Message
deserialisiert in feine entweder InitMessage
oder DataMessage
mit der Lösung here eine RuntimeTypeAdapterFactory
mit vorgeschlagen und alle möglichen Subtypen Registrierung. Die Liste DataMessage.value
ist jedoch leer (nicht deserialisiert). Das Problem ist das verschachtelte polymorphe Element in DataMessage
.
Die Adapter Fabriken:
RuntimeTypeAdapterFactory<Message> messageAdapterFactory = RuntimeTypeAdapterFactory
.of(Message.class, "MESSAGE_TYPE")
.registerSubtype(InitializationMessage.class, "INIT")
.registerSubtype(DataMessage.class, "DATA");
RuntimeTypeAdapterFactory<DataValue> dataAdapterFactory = RuntimeTypeAdapterFactory
.of(DataValue.class, "NAME")
.registerSubtype(DataValueA.class, "A")
.registerSubtype(DataValueB.class, "B")
.registerSubtype(DataValueC.class, "C");
Die Erstellung der Nachricht:
TypeToken<Message> typeToken = new TypeToken<Message>() {};
Message msg = gson.fromJson(json, typeToken.getType());
Datamessage-Klasse:
public class DataMessage extends Message {
private List<DataValue> value;
public List<DataValue> getValue() {
return value;
}
public void setValue(List<DataValue> value) {
this.value= value;
}
}
D ataValueA Klasse:
public class DataValueA extends DataValue {
private Map<String, Float> value;
public float getValue(String location) {
return value.get(location);
}
}
Die entsprechende JSON:
{
"MESSAGE_TYPE" : "DATA",
"VALUE" : [
{
"NAME" : "C",
"VALUE" : 1.3
},
{
"NAME" : "A",
"VALUE" : {
"FL" : 18.4,
"FR" : 18.4,
"RL" : 18.4,
"RR" : 18.4
}
}]
}
möchte ich die DataValue
in ihre jeweiligen Unterklasse deserialisiert werden (DataValueA
...).
Einen 'JsonDeserializer' für' Message' schreiben, der die korrekten Unterklassen erstellt und weitere Deserialisierung über 'context' delegiert. deserialize (dataObject, DataValue.class) 'gibt mir die Möglichkeit, polymorphe Nachrichten mit den polymorphen Daten zu deserialisieren. Jedoch verliere ich vollständig die Vorteile in lesbarem und wartbarem Code der Datenbindung, die mit "RuntimeTypeAdapterFactory" bereitgestellt wird. –
lschuetze