itlgl / note

使用github的issues功能记录日常的笔记
http://itlgl.com/note
5 stars 2 forks source link

Gson对于泛型的处理 #38

Open itlgl opened 5 years ago

itlgl commented 5 years ago

Gson序列化和反序列时,如果Object是泛型,那么就需要特别的处理。 假设要将一段json字符串转换为List类型,那么

处理方法一

使用TypeToken

gson.fromJson(jsonStr, new TypeToken<List<Object>>(){}.getType());

处理方法二

现在有一个问题,我想做一个统一处理方法,只要传入Object.class就可以返回List,那么还可以通过自定义ParameterizedType的方式解决。 jackson库自带了TypeFactory,调用方式是一样的,省去了自定义的麻烦。

public static class ParameterizedTypeImpl implements ParameterizedType {
    private final Class raw;
    private final Type[] args;

    public static ParameterizedTypeImpl of(Class... classes) {
        if(classes.length == 0) {
            return new ParameterizedTypeImpl(null, new Type[0]);
        }
        if(classes.length == 1) {
            return new ParameterizedTypeImpl(classes[0], null);
        }

        Type tem = classes[classes.length - 1];
        ParameterizedTypeImpl result = null;
        for (int i = classes.length - 2; i >= 0; i--) {
            result = new ParameterizedTypeImpl(classes[i], new Type[] {tem});
            tem = result;
        }
        return result;
    }

    public ParameterizedTypeImpl(Class raw, Type[] args) {
        this.raw = raw;
        this.args = args != null ? args : new Type[0];
    }

    @Override
    public Type[] getActualTypeArguments() {
        return args;
    }

    @Override
    public Type getRawType() {
        return raw;
    }

    @Override
    public Type getOwnerType() {
        return null;
    }
}

那么调用方式就变成了:

<T> T fun(Class<T> clazz) {
    String jsonStr = "...";// 省略jsonStr的联网获取代码
    return gson.fromJson(jsonStr, ParameterizedTypeImpl.of(List.class, clazz));
}

还没有深究ParameterizedType 的这么用的原理,从网上找到的代码,自己修改的。