我使用了很多不可变的集合,我很好奇如何使用Gson反序列化它们。由于没有人回答,我自己找到了解决方案,我正在简化问题并提出自己的答案。使用Gson反序列化ImmutableList
我有两个问题:
- 如何编写一个
Deserializer
所有ImmutableList<XXX>
工作? - 如何注册全部
ImmutableList<XXX>
?
我使用了很多不可变的集合,我很好奇如何使用Gson反序列化它们。由于没有人回答,我自己找到了解决方案,我正在简化问题并提出自己的答案。使用Gson反序列化ImmutableList
我有两个问题:
Deserializer
所有ImmutableList<XXX>
工作?ImmutableList<XXX>
?更新:有https://github.com/acebaggins/gson-serializers涵盖许多番石榴集合:
ImmutableList
ImmutableSet
ImmutableSortedSet
ImmutableMap
ImmutableSortedMap
如何编写一个解串器对所有ImmutableList工作?
的想法很简单,变换传递Type
表示ImmutableList<T>
为代表List<T>
一个Type
,使用内置的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);
}
}
有多种ParameterizedTypeImpl
班在我使用Java库,但他们都不打算公开使用。我用sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
进行了测试。
如何为所有ImmutableList注册它?
这部分是微不足道的,注册的第一个参数是java.lang.reflect.Type
其误导我使用ParameterizedType
,其中仅使用Class
这项工作:
final Gson gson = new GsonBuilder()
.registerTypeAdapter(ImmutableList.class, myJsonDeserializer)
.create();
@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));
}
}
还有一个小鬼lementation without 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);
}
我们可以避免使用ParameterizedTypeImpl吗?例如使用smth如: final列表> list = context.deserialize(json,List.class); –
@Alexander Bezrodniy:恐怕不可能。你可以通过使用'TypeAdapter>'来避免这一切,但是你必须写一些其他的样板代码:1。即使默认实现已经足够,也可以实现'write',2.处理'read'中的'null'。这都是一些低级别的东西。 –
maaartinus
我想我现在明白你的问题了。你不能忽略泛型;没有他们的列表内容不能正确反序列化。 – maaartinus