簡體   English   中英

使用Gson反序列化ImmutableList

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM