使用Gson反序列化ImmutableList

maa*_*nus 11 java immutability adapter gson

我正在使用相当多的不可变集合,我很好奇如何使用Gson对它们进行反序列化.由于没有人回答我自己找到了解决方案,我正在简化问题并提出自己的答案.

我有两个问题:

  • 如何Deserializer为所有人写一个单一的工作ImmutableList<XXX>
  • 如何为所有人注册ImmutableList<XXX>

maa*_*nus 10

更新:有https://github.com/acebaggins/gson-serializers,涵盖了许多番石榴收藏品:

  • ImmutableList
  • ImmutableSet
  • ImmutableSortedSet
  • ImmutableMap
  • ImmutableSortedMap

如何编写一个适用于所有ImmutableList的反序列化程序?

这个想法很简单,将传递的Type表示ImmutableList<T>转换为Type表示List<T>,使用内置Gson的功能来创建List并将其转换为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

ParameterizedTypeImpl我使用的Java库中有多个类,但没有一个用于公共用途.我测试了它sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.

如何为所有ImmutableList注册?

那部分是微不足道的,注册的第一个参数java.lang.reflect.Type误导我使用ParameterizedType,只需使用Class就可以完成工作:

final Gson gson = new GsonBuilder()
    .registerTypeAdapter(ImmutableList.class, myJsonDeserializer)
    .create();
Run Code Online (Sandbox Code Playgroud)


小智 8

还有一个没有ParameterizedTypeImpl的实现

@Override
public ImmutableList<?> deserialize(final JsonElement json, final Type type, final JsonDeserializationContext context) throws JsonParseException {
    @SuppressWarnings("unchecked")
    final TypeToken<ImmutableList<?>> immutableListToken = (TypeToken<ImmutableList<?>>) TypeToken.of(type);
    final TypeToken<? super ImmutableList<?>> listToken = immutableListToken.getSupertype(List.class);
    final List<?> list = context.deserialize(json, listToken.getType());
    return ImmutableList.copyOf(list);
}
Run Code Online (Sandbox Code Playgroud)