我使用了不少不可变的集合,我很好奇如何使用Gson对它们进行反序列化。由于没有人回答我自己找到了解决方案,我简化了问题并提出了自己的答案。
我有两个问题:
Deserializer
的单个ImmutableList<XXX>
?ImmutableList<XXX>
注册?答案 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));
}
}