Gson 源代码解析 TypeAdapterFactory ,TypeAdapter 及 自定义TypeAdapter即JsonDeserializer

父文章 

    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<HashMap<String, IWindow>> typeToken = new TypeToken<HashMap<String, IWindow>>() {
        };
        Type type = typeToken.getType();
        Map list = gson.fromJson(s, type);

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

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

   单测测试,详见 

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

这里  的GsonTest.

TypeAdapter

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

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

   用户自定义TypeAdapter的详见如下

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

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

final class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
    public JsonElement serialize(T object, Type interfaceType, JsonSerializationContext context) {
        final JsonObject wrapper = new JsonObject();
        wrapper.addProperty("type", object.getClass().getName());
        wrapper.add("data", context.serialize(object));
        return wrapper;
    }

    public T deserialize(JsonElement elem, Type interfaceType, JsonDeserializationContext context) throws JsonParseException {
        final JsonObject wrapper = (JsonObject) elem;
        final JsonElement typeName = get(wrapper, "type");
        final JsonElement data = get(wrapper, "data");
        final Type actualType = typeForName(typeName); 
        return context.deserialize(data, actualType);
    }

    private Type typeForName(final JsonElement typeElem) {
        try {
            return Class.forName(typeElem.getAsString());
        } catch (ClassNotFoundException e) {
            throw new JsonParseException(e);
        }
    }

    private JsonElement get(final JsonObject wrapper, String memberName) {
        final JsonElement elem = wrapper.get(memberName);
        if (elem == null) throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper");
        return elem;
    }
}

遇到接口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<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();

    // 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);
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值