• Gson TypeAdapter 和 TypeAdapterFactory


    父文章 

        java rpc 反序列化 泛型 接口_个人渣记录仅为自己搜索用的博客-CSDN博客

    两点待研究

    1. 实现List<接口>的序列化,反序列化.

        利用了field.setAccessible(true);

        Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());

        TypeToken fieldTypeToken = TypeToken.get(fieldType);

         TypeAdapter adapter = originalFactoriesGson.getAdapter(fieldTypeToken);

        或者
            TypeToken> typeToken = new TypeToken>() {
            };
            Type type = typeToken.getType();
            Map list = gson.fromJson(s, type);

        为什么就能获取到 泛型? java原理. 泛型会被擦除,但是封装后就能获取到. 新增了type    

      2. 为啥RuntimeTypeAdapterFactory可以,但是registerTypeHierarchyAdapter死循环? 

       单测测试,详见 

      阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台

    这里  的GsonTest.

    TypeAdapter

       作用是进行序列化和反序列化. 对于每个type会根据顺序进行适配解析. 如果找不到就用最后配置的反射adapter(详见最后)

       首先TypeAdapter子类比较多, 有顺序要求, 详见附录. 比较典型的是各种自带的基本类型的adapter和复杂类型,反射的adapter 即 ReflectiveTypeAdapterFactory.

       用户自定义TypeAdapter的详见如下

    1. Gson gson = new GsonBuilder().registerTypeAdapter(Animal.class, new InterfaceAdapter<Animal>())
    2. .create();

    来自链接接口的序列化和反序列化 java - How to serialize a class with an interface? - Stack Overflow

    1. final class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
    2. public JsonElement serialize(T object, Type interfaceType, JsonSerializationContext context) {
    3. final JsonObject wrapper = new JsonObject();
    4. wrapper.addProperty("type", object.getClass().getName());
    5. wrapper.add("data", context.serialize(object));
    6. return wrapper;
    7. }
    8. public T deserialize(JsonElement elem, Type interfaceType, JsonDeserializationContext context) throws JsonParseException {
    9. final JsonObject wrapper = (JsonObject) elem;
    10. final JsonElement typeName = get(wrapper, "type");
    11. final JsonElement data = get(wrapper, "data");
    12. final Type actualType = typeForName(typeName);
    13. return context.deserialize(data, actualType);
    14. }
    15. private Type typeForName(final JsonElement typeElem) {
    16. try {
    17. return Class.forName(typeElem.getAsString());
    18. } catch (ClassNotFoundException e) {
    19. throw new JsonParseException(e);
    20. }
    21. }
    22. private JsonElement get(final JsonObject wrapper, String memberName) {
    23. final JsonElement elem = wrapper.get(memberName);
    24. if (elem == null) throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper");
    25. return elem;
    26. }
    27. }

    遇到接口gson,不论序列化和反序列化,gson是没有对应的adapter的. 序列化可以根据object得到,但是gson考虑到反序列化的需要,还是没有擅自主张.  父类就会擅作主张,最终反序列化的时候丢失数据. 详见 阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台的ParentClazzTest

    源代码理解 Gson源码之TypeAdapterFactory_meijing11的博客-CSDN博客_typeadapterfactory

    TypeAdapterFactory

       用来创建TypeAdapter, 为啥需要factory, 因为factory往往需要将类的结构化信息动态计算出来. 序列化的时候已裸class为准. 反序列化的时候也是如此. 

       前面的TypeAdapter中的例子都是静态设置, 只对定死的type转换成自定义的序列化反序列化. 不够灵活. 典型的动态化创建adapter的例子是 https://stackoverflow.com/questions/70411051/gson-flat-down-map-to-other-fields

     详见 阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台的 TypeAdapterFactoryDemo

       也可以进一步优化, 创建adapter的时候复用 new TreeTypeAdapter(this.serializer, this.deserializer, gson, type, this) . 仅实现对应的jsonSerializer和jsonDeserializer即可,更简单. 不需要直接操作read和write.

       灵活的插件能力. 有点绕晕了. 先去理解流程, 然后才能理解或者设计一个插件,或者多层插件?  类似这里的, in, write TreeTypeAdapter 和 jsonSerializer jsonDeserializer

    补充

    所以这个问题你心里应该有了答案.

    用户对问题“对Currency对象使用ReflectiveTypeAdapter”的回答 - 问答 - 腾讯云开发者社区-腾讯云

    附录

      TypeAdapter和TypeAdapterFactory列表

    Gson()构造函数. 

     List factories = new ArrayList();

        // built-in type adapters that cannot be overridden
        factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
        factories.add(ObjectTypeAdapter.FACTORY);

        // user's type adapters 用户的
        factories.addAll(typeAdapterFactories);

        // type adapters for basic platform types
        factories.add(TypeAdapters.STRING_FACTORY);
        factories.add(TypeAdapters.INTEGER_FACTORY);
        factories.add(TypeAdapters.BOOLEAN_FACTORY);
        factories.add(TypeAdapters.BYTE_FACTORY);
        factories.add(TypeAdapters.SHORT_FACTORY);
        factories.add(TypeAdapters.newFactory(long.class, Long.class,
                longAdapter(longSerializationPolicy)));
        factories.add(TypeAdapters.newFactory(double.class, Double.class,
                doubleAdapter(serializeSpecialFloatingPointValues)));
        factories.add(TypeAdapters.newFactory(float.class, Float.class,
                floatAdapter(serializeSpecialFloatingPointValues)));
        factories.add(TypeAdapters.NUMBER_FACTORY);
        factories.add(TypeAdapters.CHARACTER_FACTORY);
        factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
        factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
        factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
        factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
        factories.add(TypeAdapters.URL_FACTORY);
        factories.add(TypeAdapters.URI_FACTORY);
        factories.add(TypeAdapters.UUID_FACTORY);
        factories.add(TypeAdapters.LOCALE_FACTORY);
        factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
        factories.add(TypeAdapters.BIT_SET_FACTORY);
        factories.add(DateTypeAdapter.FACTORY);
        factories.add(TypeAdapters.CALENDAR_FACTORY);
        factories.add(TimeTypeAdapter.FACTORY);
        factories.add(SqlDateTypeAdapter.FACTORY);
        factories.add(TypeAdapters.TIMESTAMP_FACTORY);
        factories.add(ArrayTypeAdapter.FACTORY);
        factories.add(TypeAdapters.ENUM_FACTORY);
        factories.add(TypeAdapters.CLASS_FACTORY);

        // the excluder must precede all adapters that handle user-defined types
        factories.add(excluder);

        // type adapters for composite and user-defined types
        factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
        factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
        factories.add(new ReflectiveTypeAdapterFactory(
            constructorConstructor, fieldNamingPolicy, excluder));

        this.factories = Collections.unmodifiableList(factories);
      }

  • 相关阅读:
    Java学习 --- super关键字
    前端开发重装系统,软件安装清单
    14.Java实现UDP通信
    什么是 Node.js
    Java网络编程——基本网络支持
    canvas 签名组件封装
    嵌入式Linux(树莓派)环境设置和交叉编译
    Java并发(二十一)----wait notify介绍
    Spring+CXF restful开发WebService
    【机器学习】决策树系统 | 决策树基本原理,最优划分属性,剪枝处理
  • 原文地址:https://blog.csdn.net/fei33423/article/details/127581571