[英]Deserializing ImmutableList using Gson
我正在使用許多不可變的集合,並且很好奇如何使用Gson反序列化它們。 由於沒有人回答,而且我自己找到了解決方案,因此我正在簡化問題並提出自己的答案。
我有兩個問題:
ImmutableList<XXX>
的單個Deserializer
? ImmutableList<XXX>
注冊它? 更新:有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);
}
}
我使用的Java庫中有多個ParameterizedTypeImpl
類,但是它們都不適合公共使用。 我使用sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
測試了它。
如何為所有ImmutableList注冊它?
這部分很簡單,register的第一個參數是java.lang.reflect.Type
,它使我誤以為使用ParameterizedType
,而僅使用Class
完成工作:
final Gson gson = new GsonBuilder()
.registerTypeAdapter(ImmutableList.class, myJsonDeserializer)
.create();
沒有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);
}
@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));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.