Come posso implementare il tipo TypeAdapterFactory in Gson?
Il metodo principale di creazione è generico. Perché?
Il metodo di registrazione registerTypeAdapterFactory () non riceve l’argomento type type. Quindi, come fa Gson
sapere quali classi vengono elaborate dalla fabbrica?
Devo implementare uno stabilimento per più classi o posso implementarne uno per molte classi?
Se implemento una factory per più classi, cosa dovrei restituire in caso di argomento di tipo out-of-domain?
Quando registri un adattatore di tipo normale ( GsonBuilder.registerTypeAdapter
), genera solo un adattatore di tipi per quella specifica class. Per esempio:
public abstract class Animal { abstract void speak(); } public class Dog extends Animal { private final String speech = "woof"; public void speak() { System.out.println(speech); } } // in some gson related method gsonBuilder.registerTypeAdapter(Animal.class, myTypeAdapterObject); Gson g = gsonBuilder.create(); Dog dog = new Dog(); System.out.println(g.toJson(dog));
Se hai fatto questo, Gson
non utilizzerà il tuo myTypeAdapterObject
, userà l’adattatore di tipo predefinito per Object
.
Quindi, come puoi creare un object adattatore di tipo che possa convertire QUALSIASI sottoclass di Animal
in Json? Crea un TypeAdapterFactory
! La factory può corrispondere usando il tipo generico e la class TypeToken
. Dovresti restituire null se TypeAdapterFactory
non sa come gestire un object di quel tipo.
L’altra cosa che TypeAdapterFactory
può essere utilizzata è che non è ansible colbind gli adattatori della TypeAdapterFactory
altro modo. Per impostazione predefinita, Gson non passa l’istanza di Gson
nei metodi di read
o write
di TypeAdapter
. Quindi se hai un object come:
public class MyOuterClass { private MyInnerClass inner; }
Non c’è modo di scrivere il tuo TypeAdapter
che sa come usare TypeAdapter
senza usare TypeAdapterFactory
. Il metodo TypeAdapterFactory.create
passare l’istanza di Gson
, che ti consente di insegnare a TypeAdapter
come serializzare il campo MyInnerClass
.
In generale, ecco un buon modo standard per iniziare a scrivere un’implementazione di TypeAdapterFactory
:
public enum FooAdapterFactory implements TypeAdapterFactory { INSTANCE; // Josh Bloch's Enum singleton pattern @SuppressWarnings("unchecked") @Override public TypeAdapter create(Gson gson, TypeToken type) { if (!Foo.class.isAssignableFrom(type.getRawType())) return null; // Note: You have access to the `gson` object here; you can access other deserializers using gson.getAdapter and pass them into your constructor return (TypeAdapter ) new FooAdapter(); } private static class FooAdapter extends TypeAdapter { @Override public void write(JsonWriter out, Foo value) { // your code } @Override public Foo read(JsonReader in) throws IOException { // your code } } }