问题描述
我如何实现类型 TypeAdapterFactory 在 Gson 中?
How do I implement type TypeAdapterFactory in Gson?
create 的主要方法是通用的.为什么?
The main method of create is generic. Why?
注册方法registerTypeAdapterFactory() 不接收类型参数.那么,Gson
如何知道工厂处理了哪些类?
The registration method registerTypeAdapterFactory() does not receive type a type argument. So, how does Gson
know which classes are processed by the factory?
我应该为多个类实现一个工厂,还是可以为多个类实现一个工厂?
Should I implement one factory for multiple classes, or can I implement one for many classes?
如果我为多个类实现一个工厂,那么在域外类型参数的情况下我应该返回什么?
If I implement one factory for multiple classes, then what should I return in case of out-of-domain type argument?
推荐答案
当您注册常规类型适配器 (GsonBuilder.registerTypeAdapter
) 时,它只会为该特定类生成类型适配器.例如:
When you register a regular type adapter (GsonBuilder.registerTypeAdapter
), it only generates a type adapter for THAT specific class. For example:
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));
如果你这样做了,那么Gson
将不使用你的myTypeAdapterObject
,它将使用Object.
If you did this, then Gson
will not use your myTypeAdapterObject
, it will use the default type adapter for Object
.
那么,如何制作一个可以将任何 Animal
子类转换为 Json 的类型适配器对象?创建一个 TypeAdapterFactory
!工厂可以使用泛型类型和 TypeToken
类进行匹配.如果您的 TypeAdapterFactory
不知道如何处理该类型的对象,您应该返回 null.
So, how can you make a type adapter object that can convert ANY Animal
subclass to Json? Create a TypeAdapterFactory
! The factory can match using the generic type and the TypeToken
class. You should return null if your TypeAdapterFactory
doesn't know how to handle an object of that type.
TypeAdapterFactory
的另一个用途是您不能以任何其他方式链接适配器.默认情况下,Gson 不会将您的 Gson
实例传递给 TypeAdapter
的 read
或 write
方法.因此,如果您有一个对象,例如:
The other thing TypeAdapterFactory
can be used for is that you can't CHAIN adapters any other way. By default, Gson doesn't pass your Gson
instance into the read
or write
methods of TypeAdapter
. So if you have an object like:
public class MyOuterClass {
private MyInnerClass inner;
}
如果不使用 TypeAdapterFactory
,就无法编写知道如何使用 TypeAdapter
的 TypeAdapter
.TypeAdapterFactory.create
方法确实传递了 Gson
实例,它允许你教你的 TypeAdapter
如何序列化 MyInnerClass
字段.
There is no way to write your TypeAdapter<MyOuterClass>
that knows how to use your TypeAdapter<MyInnerClass>
without using the TypeAdapterFactory
. The TypeAdapterFactory.create
method DOES pass the Gson
instance, which allows you to teach your TypeAdapter<MyOuterClass>
how to serialize the MyInnerClass
field.
通常,这里有一个很好的标准方法来开始编写 TypeAdapterFactory
的实现:
Generally, here is a good standard way to begin to write an implementation of a TypeAdapterFactory
:
public enum FooAdapterFactory implements TypeAdapterFactory {
INSTANCE; // Josh Bloch's Enum singleton pattern
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> 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<T>) new FooAdapter();
}
private static class FooAdapter extends TypeAdapter<Foo> {
@Override
public void write(JsonWriter out, Foo value) {
// your code
}
@Override
public Foo read(JsonReader in) throws IOException {
// your code
}
}
}
这篇关于如何在 Gson 中实现 TypeAdapterFactory?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!