更简单地使用TypeAdapterFactory
AFAIK可以通过TypeAdapterFactory
进行最灵活的gson定制,但是它可能会变得不必要地复杂化。 它迫使我为每个被处理的类write
,而有时只需要一个方法。 此外,有时候JsonSerializer
和/或JsonDeserializer
更容易编写,例如像这里一样 。 这引出了我这些问题:
- 是否可以编写一个简单地委托其中一个方法的
TypeAdapter
(例如将ImmutableList
写入List
写入)? - 有可能以某种方式将
JsonSerializer
和/或JsonDeserializer
与JsonDeserializer
一起使用吗? 或者,他们有工厂吗?
可以创建一个委托其方法之一的TypeAdapter
。 这个用例是API的一个重要部分,并且有一个getDelegateAdapter()方法就是为了这个目的。 this
作为getDelegateAdapter
的第一个参数传递,该参数将返回在当前工厂之后优先的适配器。
TypeAdapterFactory immutableListFactory = new TypeAdapterFactory() { @Override public TypeAdapter create(Gson gson, TypeToken type) { if (!(type.getType() instanceof ParameterizedType) || !type.getRawType().equals(ImmutableList.class)) { return null; } ParameterizedType parameterizedType = (ParameterizedType) type.getType(); TypeAdapter delegate = gson.getDelegateAdapter(this, type); TypeAdapter> elementAdapter = gson.getAdapter( TypeToken.get(parameterizedType.getActualTypeArguments()[0])); return new ImmutableListAdapter(delegate, elementAdapter); } class ImmutableListAdapter extends TypeAdapter> { private TypeAdapter> delegate; private TypeAdapter element; ImmutableListAdapter(TypeAdapter> delegate, TypeAdapter element) { this.delegate = delegate; this.element = element; } @Override public void write(JsonWriter out, ImmutableList value) throws IOException { delegate.write(out, value); } @Override public ImmutableList read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } ImmutableList.Builder builder = ImmutableList.builder(); in.beginArray(); while (in.hasNext()) { builder.add(element.read(in)); } in.endArray(); return builder.build(); } } };
您可以将JsonSerializer
/ JsonDeserializer
与TypeAdapterFactory
混合使用,但不能直接使用。 最简单的方法是回调Gson以序列化类中的子值。 在这个例子中,我们将内部循环更改为:
while (in.hasNext()) { builder.add(gson.fromJson(in, elementType)); }
JsonSerializer
/ JsonDeserializer
和TypeAdapter
之间的主要区别在于从JSON到对象模型需要多少个阶段。 使用JsonSerializer
/ JsonDeserializer
对象首先转换为Gson的DOM模型( JsonElement
等),然后转换为您的对象模型。 使用TypeAdapter
,将跳过中间步骤。
这使得类型适配器代码的读写变得有点棘手,因此您应该优先考虑优化代码。