使用Gson反序列化ImmutableList

时间:2011-10-09 21:47:19

标签: java adapter immutability gson

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

我有两个问题:

  • 如何编写适用于所有Deserializer的单个ImmutableList<XXX>
  • 如何为所有ImmutableList<XXX>注册?

3 个答案:

答案 0 :(得分:10)

更新:https://github.com/acebaggins/gson-serializers涵盖了许多番石榴集合:

  • ImmutableList
  • ImmutableSet
  • ImmutableSortedSet
  • ImmutableMap
  • ImmutableSortedMap

  

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

这个想法很简单,将代表Type的传递ImmutableList<T>转换为代表Type的{​​{1}},使用内置List<T>的功能创建Gson并将其转换为List

ImmutableList

我使用的Java库中有多个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); } } 类,但没有一个用于公共用途。我用ParameterizedTypeImpl测试了它。

  

如何为所有ImmutableList注册?

这一部分是微不足道的,注册的第一个参数是sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl,误导我使用java.lang.reflect.Type,只需使用ParameterizedType即可完成工作:

Class

答案 1 :(得分: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);
}

答案 2 :(得分:2)

@maaartinus已经涵盖了第二个问题,因此我将在第一个问题上发布基于番石榴的补充解决方案,该问题不需要ParametrizedTypeImpl

public final class ImmutableListDeserializer implements JsonDeserializer<ImmutableList<?>> {
  @Override
  public ImmutableList<?> deserialize(final JsonElement json, final Type type,
                                      final JsonDeserializationContext context)
      throws JsonParseException {
    final Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
    final Type parameterizedType = listOf(typeArguments[0]).getType();
    final List<?> list = context.deserialize(json, parameterizedType);
    return ImmutableList.copyOf(list);
  }

  private static <E> TypeToken<List<E>> listOf(final Type arg) {
    return new TypeToken<List<E>>() {}
        .where(new TypeParameter<E>() {}, (TypeToken<E>) TypeToken.of(arg));   
  }
}