Come posso implementare TypeAdapterFactory in Gson?

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 } } }