Update: C'è https://github.com/acebaggins/gson-serializers che copre molte collezioni guava:
ImmutableList
ImmutableSet
ImmutableSortedSet
ImmutableMap
ImmutableSortedMap
Come scrivere una sola Deserializer di lavoro per tutti ImmutableList?
L'idea è semplice, trasformare il passato Type
che rappresenta un ImmutableList<T>
in un Type
che rappresenta List<T>
, utilizzare il build-in capacità Gson
s' per creare un List
e convertirlo in un ImmutableList
.
class MyJsonDeserializer implements JsonDeserializer<ImmutableList<?>> {
@Override
public ImmutableList<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
final Type type2 = ParameterizedTypeImpl.make(List.class, ((ParameterizedType) type).getActualTypeArguments(), null);
final List<?> list = context.deserialize(json, type2);
return ImmutableList.copyOf(list);
}
}
ci sono più ParameterizedTypeImpl
classi in librerie Java che uso, ma nessuno di loro destinati per l'uso pubblico. L'ho provato con sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
.
Come registrarlo per tutti ImmutableList?
Quella parte è banale, il primo argomento di registrare è java.lang.reflect.Type
che mi indurre in errore di utilizzare ParameterizedType
, dove semplicemente utilizzando Class
fa il lavoro:
final Gson gson = new GsonBuilder()
.registerTypeAdapter(ImmutableList.class, myJsonDeserializer)
.create();
È possibile evitare l'utilizzo di ParameterizedTypeImpl? Ad esempio usando smth come: final List > list = context.deserialize (json, List.class); –
@Alexander Bezrodniy: ho paura, non è possibile. Puoi evitare tutto usando un 'TypeAdapter>', ma poi devi scrivere qualche altro codice boilerplate: 1.Implementa 'write' anche se l'implementazione predefinita sarebbe sufficiente, 2. Gestisci' null' in 'read'. È tutto roba di basso livello. –
maaartinus
Credo che ora capisco la tua domanda. Non puoi lasciare fuori i generici; senza di essi il contenuto della lista non può essere deserializzato correttamente. – maaartinus